@@ -4,7 +4,7 @@ use rustc_type_ir::data_structures::IndexSet;
4
4
use rustc_type_ir:: fast_reject:: DeepRejectCtxt ;
5
5
use rustc_type_ir:: inherent:: * ;
6
6
use rustc_type_ir:: lang_items:: SolverTraitLangItem ;
7
- use rustc_type_ir:: solve:: { CanonicalResponse , SizedTraitKind } ;
7
+ use rustc_type_ir:: solve:: { CandidatePreferenceMode , CanonicalResponse , SizedTraitKind } ;
8
8
use rustc_type_ir:: {
9
9
self as ty, Interner , Movability , PredicatePolarity , TraitPredicate , TraitRef ,
10
10
TypeVisitableExt as _, TypingMode , Upcast as _, elaborate,
@@ -1355,6 +1355,7 @@ where
1355
1355
#[ instrument( level = "debug" , skip( self ) , ret) ]
1356
1356
pub ( super ) fn merge_trait_candidates (
1357
1357
& mut self ,
1358
+ candidate_preference_mode : CandidatePreferenceMode ,
1358
1359
mut candidates : Vec < Candidate < I > > ,
1359
1360
failed_candidate_info : FailedCandidateInfo ,
1360
1361
) -> Result < ( CanonicalResponse < I > , Option < TraitGoalProvenVia > ) , NoSolution > {
@@ -1380,6 +1381,24 @@ where
1380
1381
return Ok ( ( candidate. result , Some ( TraitGoalProvenVia :: Misc ) ) ) ;
1381
1382
}
1382
1383
1384
+ let potential_alias_bound_response =
1385
+ candidates. iter ( ) . any ( |c| matches ! ( c. source, CandidateSource :: AliasBound ) ) . then ( || {
1386
+ let alias_bounds: Vec < _ > = candidates
1387
+ . extract_if ( .., |c| matches ! ( c. source, CandidateSource :: AliasBound ) )
1388
+ . collect ( ) ;
1389
+ if let Some ( ( response, _) ) = self . try_merge_candidates ( & alias_bounds) {
1390
+ ( response, Some ( TraitGoalProvenVia :: AliasBound ) )
1391
+ } else {
1392
+ ( self . bail_with_ambiguity ( & alias_bounds) , None )
1393
+ }
1394
+ } ) ;
1395
+
1396
+ if matches ! ( candidate_preference_mode, CandidatePreferenceMode :: Marker )
1397
+ && let Some ( alias_bound_response) = potential_alias_bound_response
1398
+ {
1399
+ return Ok ( alias_bound_response) ;
1400
+ }
1401
+
1383
1402
// If there are non-global where-bounds, prefer where-bounds
1384
1403
// (including global ones) over everything else.
1385
1404
let has_non_global_where_bounds = candidates
@@ -1427,15 +1446,8 @@ where
1427
1446
} ;
1428
1447
}
1429
1448
1430
- if candidates. iter ( ) . any ( |c| matches ! ( c. source, CandidateSource :: AliasBound ) ) {
1431
- let alias_bounds: Vec < _ > = candidates
1432
- . extract_if ( .., |c| matches ! ( c. source, CandidateSource :: AliasBound ) )
1433
- . collect ( ) ;
1434
- return if let Some ( ( response, _) ) = self . try_merge_candidates ( & alias_bounds) {
1435
- Ok ( ( response, Some ( TraitGoalProvenVia :: AliasBound ) ) )
1436
- } else {
1437
- Ok ( ( self . bail_with_ambiguity ( & alias_bounds) , None ) )
1438
- } ;
1449
+ if let Some ( response) = potential_alias_bound_response {
1450
+ return Ok ( response) ;
1439
1451
}
1440
1452
1441
1453
self . filter_specialized_impls ( AllowInferenceConstraints :: No , & mut candidates) ;
@@ -1470,7 +1482,9 @@ where
1470
1482
) -> Result < ( CanonicalResponse < I > , Option < TraitGoalProvenVia > ) , NoSolution > {
1471
1483
let ( candidates, failed_candidate_info) =
1472
1484
self . assemble_and_evaluate_candidates ( goal, AssembleCandidatesFrom :: All ) ;
1473
- self . merge_trait_candidates ( candidates, failed_candidate_info)
1485
+ let candidate_preference_mode =
1486
+ CandidatePreferenceMode :: compute ( self . cx ( ) , goal. predicate . def_id ( ) ) ;
1487
+ self . merge_trait_candidates ( candidate_preference_mode, candidates, failed_candidate_info)
1474
1488
}
1475
1489
1476
1490
fn try_stall_coroutine ( & mut self , self_ty : I :: Ty ) -> Option < Result < Candidate < I > , NoSolution > > {
0 commit comments