@@ -44,30 +44,43 @@ impl<I: Interner> Solution<I> {
4444 /// There are multiple candidate solutions, which may or may not agree on
4545 /// the values for existential variables; attempt to combine them. This
4646 /// operation does not depend on the order of its arguments.
47- //
48- // This actually isn't as precise as it could be, in two ways:
49- //
50- // a. It might be that while there are multiple distinct candidates, they
51- // all agree about *some things*. To be maximally precise, we would
52- // compute the intersection of what they agree on. It's not clear though
53- // that this is actually what we want Rust's inference to do, and it's
54- // certainly not what it does today.
55- //
56- // b. There might also be an ambiguous candidate and a successful candidate,
57- // both with the same refined-goal. In that case, we could probably claim
58- // success, since if the conditions of the ambiguous candidate were met,
59- // we know the success would apply. Example: `?0: Clone` yields ambiguous
60- // candidate `Option<?0>: Clone` and successful candidate `Option<?0>:
61- // Clone`.
62- //
63- // But you get the idea.
47+ ///
48+ /// This actually isn't as precise as it could be, in two ways:
49+ ///
50+ /// a. It might be that while there are multiple distinct candidates, they
51+ /// all agree about *some things*. To be maximally precise, we would
52+ /// compute the intersection of what they agree on. It's not clear though
53+ /// that this is actually what we want Rust's inference to do, and it's
54+ /// certainly not what it does today.
55+ ///
56+ /// b. There might also be an ambiguous candidate and a successful candidate,
57+ /// both with the same refined-goal. In that case, we could probably claim
58+ /// success, since if the conditions of the ambiguous candidate were met,
59+ /// we know the success would apply. Example: `?0: Clone` yields ambiguous
60+ /// candidate `Option<?0>: Clone` and successful candidate `Option<?0>:
61+ /// Clone`.
62+ ///
63+ /// But you get the idea.
6464 pub fn combine ( self , other : Solution < I > , interner : I ) -> Solution < I > {
6565 use self :: Guidance :: * ;
6666
6767 if self == other {
6868 return self ;
6969 }
7070
71+ // Special case hack: if one solution is "true" without any constraints,
72+ // that is always the combined result.
73+ //
74+ // This is not as general as it could be: ideally, if we had one solution
75+ // that is Unique with a simpler substitution than the other one, or region constraints
76+ // which are a subset, we'd combine them.
77+ if self . is_trivial_and_always_true ( interner) {
78+ return self ;
79+ }
80+ if other. is_trivial_and_always_true ( interner) {
81+ return other;
82+ }
83+
7184 debug ! (
7285 "combine {} with {}" ,
7386 self . display( interner) ,
@@ -88,6 +101,16 @@ impl<I: Interner> Solution<I> {
88101 Solution :: Ambig ( guidance)
89102 }
90103
104+ pub fn is_trivial_and_always_true ( & self , interner : I ) -> bool {
105+ match self {
106+ Solution :: Unique ( constrained_subst) => {
107+ constrained_subst. value . subst . is_identity_subst ( interner)
108+ && constrained_subst. value . constraints . is_empty ( interner)
109+ }
110+ Solution :: Ambig ( _) => false ,
111+ }
112+ }
113+
91114 /// View this solution purely in terms of type inference guidance
92115 pub fn into_guidance ( self ) -> Guidance < I > {
93116 match self {
0 commit comments