@@ -8,6 +8,7 @@ use rustc_type_ir::lang_items::TraitSolverLangItem;
8
8
use rustc_type_ir:: solve:: CanonicalResponse ;
9
9
use rustc_type_ir:: visit:: TypeVisitableExt as _;
10
10
use rustc_type_ir:: { self as ty, Interner , TraitPredicate , TypingMode , Upcast as _, elaborate} ;
11
+ use smallvec:: SmallVec ;
11
12
use tracing:: { instrument, trace} ;
12
13
13
14
use crate :: delegate:: SolverDelegate ;
@@ -225,7 +226,7 @@ where
225
226
}
226
227
227
228
ecx. probe_and_evaluate_goal_for_constituent_tys (
228
- CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Misc ) ,
229
+ CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Trivial ) ,
229
230
goal,
230
231
structural_traits:: instantiate_constituent_tys_for_sized_trait,
231
232
)
@@ -1194,7 +1195,30 @@ where
1194
1195
} ;
1195
1196
}
1196
1197
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
+ }
1198
1222
1199
1223
// If there are non-global where-bounds, prefer where-bounds
1200
1224
// (including global ones) over everything else.
0 commit comments