@@ -9,6 +9,7 @@ mod structural_impls;
9
9
pub mod util;
10
10
11
11
use std:: cmp;
12
+ use std:: hash:: { Hash , Hasher } ;
12
13
13
14
use hir:: def_id:: LocalDefId ;
14
15
use rustc_hir as hir;
@@ -36,7 +37,7 @@ pub use rustc_middle::traits::*;
36
37
/// either identifying an `impl` (e.g., `impl Eq for i32`) that
37
38
/// satisfies the obligation, or else finding a bound that is in
38
39
/// scope. The eventual result is usually a `Selection` (defined below).
39
- #[ derive( Clone , PartialEq , Eq , Hash ) ]
40
+ #[ derive( Clone ) ]
40
41
pub struct Obligation < ' tcx , T > {
41
42
/// The reason we have to prove this thing.
42
43
pub cause : ObligationCause < ' tcx > ,
@@ -55,6 +56,27 @@ pub struct Obligation<'tcx, T> {
55
56
pub recursion_depth : usize ,
56
57
}
57
58
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
+
58
80
impl < ' tcx , P > From < Obligation < ' tcx , P > > for solve:: Goal < ' tcx , P > {
59
81
fn from ( value : Obligation < ' tcx , P > ) -> Self {
60
82
solve:: Goal { param_env : value. param_env , predicate : value. predicate }
0 commit comments