@@ -8,6 +8,7 @@ use rustc_type_ir::lang_items::TraitSolverLangItem;
88use rustc_type_ir:: solve:: CanonicalResponse ;
99use rustc_type_ir:: visit:: TypeVisitableExt as _;
1010use rustc_type_ir:: { self as ty, Interner , TraitPredicate , TypingMode , Upcast as _, elaborate} ;
11+ use smallvec:: SmallVec ;
1112use tracing:: { instrument, trace} ;
1213
1314use crate :: delegate:: SolverDelegate ;
@@ -225,7 +226,7 @@ where
225226 }
226227
227228 ecx. probe_and_evaluate_goal_for_constituent_tys (
228- CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Misc ) ,
229+ CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Trivial ) ,
229230 goal,
230231 structural_traits:: instantiate_constituent_tys_for_sized_trait,
231232 )
@@ -1194,7 +1195,30 @@ where
11941195 } ;
11951196 }
11961197
1197- // FIXME: prefer trivial builtin impls
1198+ // We prefer trivial builtin candidates, i.e. builtin impls without any
1199+ // nested requirements, over all others. This is a fix for #53123 and
1200+ // prevents where-bounds from accidentally extending the lifetime of a
1201+ // variable.
1202+ if candidates
1203+ . iter ( )
1204+ . any ( |c| matches ! ( c. source, CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Trivial ) ) )
1205+ {
1206+ let trivial_builtin_impls: SmallVec < [ _ ; 1 ] > = candidates
1207+ . iter ( )
1208+ . filter ( |c| {
1209+ matches ! ( c. source, CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Trivial ) )
1210+ } )
1211+ . map ( |c| c. result )
1212+ . collect ( ) ;
1213+ // There should only ever be a single trivial builtin candidate
1214+ // as they would otherwise overlap.
1215+ assert_eq ! ( trivial_builtin_impls. len( ) , 1 ) ;
1216+ return if let Some ( response) = self . try_merge_responses ( & trivial_builtin_impls) {
1217+ Ok ( ( response, Some ( TraitGoalProvenVia :: Misc ) ) )
1218+ } else {
1219+ Ok ( ( self . bail_with_ambiguity ( & trivial_builtin_impls) , None ) )
1220+ } ;
1221+ }
11981222
11991223 // If there are non-global where-bounds, prefer where-bounds
12001224 // (including global ones) over everything else.
0 commit comments