@@ -9,6 +9,7 @@ mod structural_impls;
99pub mod util;
1010
1111use std:: cmp;
12+ use std:: hash:: { Hash , Hasher } ;
1213
1314use hir:: def_id:: LocalDefId ;
1415use rustc_hir as hir;
@@ -36,7 +37,7 @@ pub use rustc_middle::traits::*;
3637/// either identifying an `impl` (e.g., `impl Eq for i32`) that
3738/// satisfies the obligation, or else finding a bound that is in
3839/// scope. The eventual result is usually a `Selection` (defined below).
39- #[ derive( Clone , PartialEq , Eq , Hash ) ]
40+ #[ derive( Clone ) ]
4041pub struct Obligation < ' tcx , T > {
4142 /// The reason we have to prove this thing.
4243 pub cause : ObligationCause < ' tcx > ,
@@ -55,6 +56,27 @@ pub struct Obligation<'tcx, T> {
5556 pub recursion_depth : usize ,
5657}
5758
59+ impl < ' tcx , T : PartialEq > PartialEq < Obligation < ' tcx , T > > for Obligation < ' tcx , T > {
60+ #[ inline]
61+ fn eq ( & self , other : & Obligation < ' tcx , T > ) -> bool {
62+ // Ignore `cause` and `recursion_depth`. This is a small performance
63+ // win for a few crates, and a huge performance win for the crate in
64+ // https://github.com/rust-lang/rustc-perf/pull/1680, which greatly
65+ // stresses the trait system.
66+ self . param_env == other. param_env && self . predicate == other. predicate
67+ }
68+ }
69+
70+ impl < T : Eq > Eq for Obligation < ' _ , T > { }
71+
72+ impl < T : Hash > Hash for Obligation < ' _ , T > {
73+ fn hash < H : Hasher > ( & self , state : & mut H ) -> ( ) {
74+ // See the comment on `Obligation::eq`.
75+ self . param_env . hash ( state) ;
76+ self . predicate . hash ( state) ;
77+ }
78+ }
79+
5880impl < ' tcx , P > From < Obligation < ' tcx , P > > for solve:: Goal < ' tcx , P > {
5981 fn from ( value : Obligation < ' tcx , P > ) -> Self {
6082 solve:: Goal { param_env : value. param_env , predicate : value. predicate }
0 commit comments