@@ -13,6 +13,7 @@ use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
1313use crate :: util:: captures:: Captures ;
1414use crate :: mir:: interpret:: { Scalar , Pointer , Allocation } ;
1515
16+ use std:: hash:: { Hash , Hasher } ;
1617use smallvec:: SmallVec ;
1718use std:: iter;
1819use std:: cmp:: Ordering ;
@@ -2086,7 +2087,7 @@ impl<'tcx> LazyConst<'tcx> {
20862087}
20872088
20882089/// 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 ) ]
20902091pub struct Const < ' tcx > {
20912092 pub ty : Ty < ' tcx > ,
20922093
@@ -2104,6 +2105,46 @@ pub struct Const<'tcx> {
21042105 pub alloc : Option < ( & ' tcx Allocation , Pointer ) > ,
21052106}
21062107
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+
21072148#[ cfg( target_arch = "x86_64" ) ]
21082149static_assert ! ( CONST_SIZE : :: std:: mem:: size_of:: <Const <' static >>( ) == 72 ) ;
21092150
0 commit comments