@@ -13,6 +13,7 @@ use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
13
13
use crate :: util:: captures:: Captures ;
14
14
use crate :: mir:: interpret:: { Scalar , Pointer , Allocation } ;
15
15
16
+ use std:: hash:: { Hash , Hasher } ;
16
17
use smallvec:: SmallVec ;
17
18
use std:: iter;
18
19
use std:: cmp:: Ordering ;
@@ -2086,7 +2087,7 @@ impl<'tcx> LazyConst<'tcx> {
2086
2087
}
2087
2088
2088
2089
/// Typed constant value.
2089
- #[ derive( Copy , Clone , Debug , Hash , RustcEncodable , RustcDecodable , Eq , PartialEq , Ord , PartialOrd ) ]
2090
+ #[ derive( Copy , Clone , Debug , RustcEncodable , RustcDecodable , Eq , Ord , PartialOrd ) ]
2090
2091
pub struct Const < ' tcx > {
2091
2092
pub ty : Ty < ' tcx > ,
2092
2093
@@ -2104,6 +2105,46 @@ pub struct Const<'tcx> {
2104
2105
pub alloc : Option < ( & ' tcx Allocation , Pointer ) > ,
2105
2106
}
2106
2107
2108
+ impl < ' tcx > PartialEq for Const < ' tcx > {
2109
+ fn eq ( & self , other : & Self ) -> bool {
2110
+
2111
+ self . ty == other. ty && match ( self . val , other. val ) {
2112
+ ( ConstValue :: ByRef , ConstValue :: ByRef ) => {
2113
+ let ( a, pa) = self . alloc . unwrap ( ) ;
2114
+ let ( b, pb) = other. alloc . unwrap ( ) ;
2115
+ // only use the alloc ids to not have to compare the full allocations
2116
+ // the ids may differ if the allocation is the same
2117
+ ( pa. offset == pb. offset ) && ( pa. alloc_id == pb. alloc_id || a == b)
2118
+ } ,
2119
+ // ignore the actual allocation, just compare the values
2120
+ ( ConstValue :: Scalar ( a) , ConstValue :: Scalar ( b) ) => a == b,
2121
+ ( ConstValue :: Slice ( a, an) , ConstValue :: Slice ( b, bn) ) => an == bn && a == b,
2122
+ // if the values don't match, the consts can't be equal and the type equality should
2123
+ // have already failed, because we make the decision for non-byref solely based on the
2124
+ // type
2125
+ _ => bug ! ( "same type but different value kind in constant: {:#?} {:#?}" , self , other) ,
2126
+ }
2127
+ }
2128
+ }
2129
+
2130
+ impl < ' tcx > Hash for Const < ' tcx > {
2131
+ fn hash < H : Hasher > ( & self , hasher : & mut H ) {
2132
+ let Const { ty, val, alloc } = self ;
2133
+ ty. hash ( hasher) ;
2134
+ val. hash ( hasher) ;
2135
+ if let ConstValue :: ByRef = val {
2136
+ let ( alloc, ptr) = alloc. unwrap ( ) ;
2137
+ // type check for future changes
2138
+ let alloc: & ' tcx Allocation = alloc;
2139
+ alloc. hash ( hasher) ;
2140
+ ptr. offset . hash ( hasher) ;
2141
+ // do not hash the alloc id in the pointer. It does not add anything new to the hash.
2142
+ // If the hash of the alloc id is the same, then the hash of the allocation would also
2143
+ // be the same.
2144
+ }
2145
+ }
2146
+ }
2147
+
2107
2148
#[ cfg( target_arch = "x86_64" ) ]
2108
2149
static_assert ! ( CONST_SIZE : :: std:: mem:: size_of:: <Const <' static >>( ) == 72 ) ;
2109
2150
0 commit comments