@@ -209,9 +209,13 @@ where
209209 then : impl FnOnce ( & mut EvalCtxt < ' _ , D > ) -> QueryResultOrRerunNonErased < I > ,
210210 ) -> QueryResultOrRerunNonErased < I > ;
211211
212+ /// Note: `goal_trait_ref` is derived from `goal`. Nonetheless, because
213+ /// `consider_impl_candidate` is always called in a loop, we precompute `goal_trait_ref` once
214+ /// and pass it in next to `goal` because the computation is expensive and loop-invariant.
212215 fn consider_impl_candidate (
213216 ecx : & mut EvalCtxt < ' _ , D > ,
214217 goal : Goal < I , Self > ,
218+ goal_trait_ref : ty:: TraitRef < I > ,
215219 impl_def_id : I :: ImplId ,
216220 then : impl FnOnce ( & mut EvalCtxt < ' _ , D > , Certainty ) -> QueryResultOrRerunNonErased < I > ,
217221 ) -> Result < Candidate < I > , NoSolutionOrRerunNonErased > ;
@@ -545,19 +549,25 @@ where
545549 candidates : & mut Vec < Candidate < I > > ,
546550 ) -> Result < ( ) , RerunNonErased > {
547551 let cx = self . cx ( ) ;
548- cx. for_each_relevant_impl ( goal. predicate . trait_ref ( cx) , |impl_def_id| -> Result < _ , _ > {
549- // For every `default impl`, there's always a non-default `impl`
550- // that will *also* apply. There's no reason to register a candidate
551- // for this impl, since it is *not* proof that the trait goal holds.
552- if cx. impl_is_default ( impl_def_id) {
553- return Ok ( ( ) ) ;
554- }
555- match G :: consider_impl_candidate ( self , goal, impl_def_id, |ecx, certainty| {
556- ecx. evaluate_added_goals_and_make_canonical_response ( certainty)
557- } )
552+ let goal_trait_ref = goal. predicate . trait_ref ( cx) ;
553+ cx. for_each_relevant_impl ( goal_trait_ref, |impl_def_id| -> Result < _ , _ > {
554+ match G :: consider_impl_candidate (
555+ self ,
556+ goal,
557+ goal_trait_ref,
558+ impl_def_id,
559+ |ecx, certainty| ecx. evaluate_added_goals_and_make_canonical_response ( certainty) ,
560+ )
558561 . map_err_to_rerun ( ) ?
559562 {
560- Ok ( candidate) => candidates. push ( candidate) ,
563+ Ok ( candidate) => {
564+ // For every `default impl`, there's always a non-default `impl`
565+ // that will *also* apply. There's no reason to register a candidate
566+ // for this impl, since it is *not* proof that the trait goal holds.
567+ if !cx. impl_is_default ( impl_def_id) {
568+ candidates. push ( candidate) ;
569+ }
570+ }
561571 Err ( NoSolution ) => { }
562572 }
563573
@@ -1165,6 +1175,7 @@ where
11651175 // See tests/ui/impl-trait/non-defining-uses/use-blanket-impl.rs for an example.
11661176 if assemble_from. should_assemble_impl_candidates ( ) {
11671177 let cx = self . cx ( ) ;
1178+ let goal_trait_ref = goal. predicate . trait_ref ( cx) ;
11681179 cx. for_each_blanket_impl ( goal. predicate . trait_def_id ( cx) , |impl_def_id| {
11691180 // For every `default impl`, there's always a non-default `impl`
11701181 // that will *also* apply. There's no reason to register a candidate
@@ -1173,20 +1184,26 @@ where
11731184 return Ok ( ( ) ) ;
11741185 }
11751186
1176- match G :: consider_impl_candidate ( self , goal, impl_def_id, |ecx, certainty| {
1177- if ecx. shallow_resolve ( self_ty) . is_ty_var ( ) {
1178- // We force the certainty of impl candidates to be `Maybe`.
1179- let certainty = certainty. and ( Certainty :: AMBIGUOUS ) ;
1180- ecx. evaluate_added_goals_and_make_canonical_response ( certainty)
1181- } else {
1182- // We don't want to use impls if they constrain the opaque.
1183- //
1184- // FIXME(trait-system-refactor-initiative#229): This isn't
1185- // perfect yet as it still allows us to incorrectly constrain
1186- // other inference variables.
1187- Err ( NoSolution . into ( ) )
1188- }
1189- } )
1187+ match G :: consider_impl_candidate (
1188+ self ,
1189+ goal,
1190+ goal_trait_ref,
1191+ impl_def_id,
1192+ |ecx, certainty| {
1193+ if ecx. shallow_resolve ( self_ty) . is_ty_var ( ) {
1194+ // We force the certainty of impl candidates to be `Maybe`.
1195+ let certainty = certainty. and ( Certainty :: AMBIGUOUS ) ;
1196+ ecx. evaluate_added_goals_and_make_canonical_response ( certainty)
1197+ } else {
1198+ // We don't want to use impls if they constrain the opaque.
1199+ //
1200+ // FIXME(trait-system-refactor-initiative#229): This isn't
1201+ // perfect yet as it still allows us to incorrectly constrain
1202+ // other inference variables.
1203+ Err ( NoSolution . into ( ) )
1204+ }
1205+ } ,
1206+ )
11901207 . map_err_to_rerun ( ) ?
11911208 {
11921209 Ok ( candidate) => candidates. push ( candidate) ,
0 commit comments