@@ -58,6 +58,12 @@ impl<'tcx> inspect::ProofTreeVisitor<'tcx> for Select {
58
58
) ) ) ;
59
59
}
60
60
61
+ // Don't winnow until `Certainty::Yes` -- we don't need to winnow until
62
+ // codegen, and only on the good path.
63
+ if matches ! ( goal. result( ) . unwrap( ) , Certainty :: Maybe ( ..) ) {
64
+ return ControlFlow :: Break ( Ok ( None ) ) ;
65
+ }
66
+
61
67
// We need to winnow. See comments on `candidate_should_be_dropped_in_favor_of`.
62
68
let mut i = 0 ;
63
69
while i < candidates. len ( ) {
@@ -86,7 +92,7 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>(
86
92
other : & inspect:: InspectCandidate < ' _ , ' tcx > ,
87
93
) -> bool {
88
94
// Don't winnow until `Certainty::Yes` -- we don't need to winnow until
89
- // codegen, technically .
95
+ // codegen, and only on the good path .
90
96
if matches ! ( other. result( ) . unwrap( ) , Certainty :: Maybe ( ..) ) {
91
97
return false ;
92
98
}
@@ -105,12 +111,14 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>(
105
111
bug ! ( "should not have assembled a CoherenceUnknowable candidate" )
106
112
}
107
113
114
+ // In the old trait solver, we arbitrarily choose lower vtable candidates
115
+ // over higher ones.
116
+ (
117
+ CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Object { vtable_base : a } ) ,
118
+ CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Object { vtable_base : b } ) ,
119
+ ) => a >= b,
108
120
// Prefer dyn candidates over non-dyn candidates. This is necessary to
109
121
// handle the unsoundness between `impl<T: ?Sized> Any for T` and `dyn Any: Any`.
110
- (
111
- CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Object { .. } ) ,
112
- CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Object { .. } ) ,
113
- ) => false ,
114
122
(
115
123
CandidateSource :: Impl ( _) | CandidateSource :: ParamEnv ( _) | CandidateSource :: AliasBound ,
116
124
CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Object { .. } ) ,
0 commit comments