@@ -16,8 +16,8 @@ use crate::solve::assembly::structural_traits::{self, AsyncCallableRelevantTypes
1616use  crate :: solve:: assembly:: { self ,  AllowInferenceConstraints ,  AssembleCandidatesFrom ,  Candidate } ; 
1717use  crate :: solve:: inspect:: ProbeKind ; 
1818use  crate :: solve:: { 
19-     BuiltinImplSource ,  CandidateSource ,  Certainty ,  EvalCtxt ,  Goal ,  GoalSource ,   MaybeCause , 
20-     NoSolution ,  ParamEnvSource ,  QueryResult ,  has_only_region_constraints, 
19+     BuiltinImplSource ,  CandidateSource ,  Candidates ,   Certainty ,  EvalCtxt ,  Goal ,  GoalSource , 
20+     MaybeCause ,   NoSolution ,  ParamEnvSource ,  QueryResult ,  has_only_region_constraints, 
2121} ; 
2222
2323impl < D ,  I >  assembly:: GoalKind < D >  for  TraitPredicate < I > 
@@ -1343,22 +1343,20 @@ where
13431343    #[ instrument( level = "debug" ,  skip( self ) ,  ret) ]  
13441344    pub ( super )  fn  merge_trait_candidates ( 
13451345        & mut  self , 
1346-         mut  candidates :  Vec < Candidate < I > > , 
1346+         mut  candidates :  Candidates < I > , 
13471347    )  -> Result < ( CanonicalResponse < I > ,  Option < TraitGoalProvenVia > ) ,  NoSolution >  { 
13481348        if  let  TypingMode :: Coherence  = self . typing_mode ( )  { 
1349-             let  all_candidates:  Vec < _ >  = candidates. into_iter ( ) . map ( |c| c. result ) . collect ( ) ; 
1350-             return  if  let  Some ( response)  = self . try_merge_responses ( & all_candidates)  { 
1351-                 Ok ( ( response,  Some ( TraitGoalProvenVia :: Misc ) ) ) 
1352-             }  else  { 
1353-                 self . flounder ( & all_candidates) . map ( |r| ( r,  None ) ) 
1354-             } ; 
1349+             match  self . try_merge_candidates ( candidates. applicable ,  vec ! [ ] )  { 
1350+                 Ok ( response)  => return  Ok ( ( response,  Some ( TraitGoalProvenVia :: Misc ) ) ) , 
1351+                 Err ( candidates)  => return  self . flounder ( & candidates) . map ( |r| ( r,  None ) ) , 
1352+             } 
13551353        } 
13561354
13571355        // We prefer trivial builtin candidates, i.e. builtin impls without any 
13581356        // nested requirements, over all others. This is a fix for #53123 and 
13591357        // prevents where-bounds from accidentally extending the lifetime of a 
13601358        // variable. 
1361-         let  mut  trivial_builtin_impls = candidates. iter ( ) . filter ( |c| { 
1359+         let  mut  trivial_builtin_impls = candidates. applicable . iter ( ) . filter ( |c| { 
13621360            matches ! ( c. source,  CandidateSource :: BuiltinImpl ( BuiltinImplSource :: Trivial ) ) 
13631361        } ) ; 
13641362        if  let  Some ( candidate)  = trivial_builtin_impls. next ( )  { 
@@ -1371,57 +1369,56 @@ where
13711369        // If there are non-global where-bounds, prefer where-bounds 
13721370        // (including global ones) over everything else. 
13731371        let  has_non_global_where_bounds = candidates
1372+             . applicable 
13741373            . iter ( ) 
13751374            . any ( |c| matches ! ( c. source,  CandidateSource :: ParamEnv ( ParamEnvSource :: NonGlobal ) ) ) ; 
13761375        if  has_non_global_where_bounds { 
1377-             let  where_bounds:   Vec < _ >   = candidates
1378-                  . iter ( ) 
1379-                 . filter ( |c| matches ! ( c. source,  CandidateSource :: ParamEnv ( _) ) ) 
1380-                  . map ( |c| c . result ) 
1381-                 . collect ( ) ; 
1382-             return   if   let   Some ( response )  =  self . try_merge_responses ( & where_bounds )   { 
1383-                  Ok ( ( response ,   Some ( TraitGoalProvenVia :: ParamEnv ) ) ) 
1384-             }   else   { 
1385-                 Ok ( ( self . bail_with_ambiguity ( & where_bounds) ,  None ) ) 
1386-             } ; 
1376+             let  mut   where_bounds  = candidates. applicable ; 
1377+             for  not_where_bound  in 
1378+                 where_bounds . extract_if ( .. ,   |c| ! matches ! ( c. source,  CandidateSource :: ParamEnv ( _) ) ) 
1379+             { 
1380+                 self . ignore_candidate_usages ( not_where_bound . candidate_usages ) ; 
1381+             } 
1382+             match   self . try_merge_candidates ( where_bounds ,  candidates . not_applicable_param_env )   { 
1383+                  Ok ( response )  =>  return   Ok ( ( response ,   Some ( TraitGoalProvenVia :: ParamEnv ) ) ) , 
1384+                 Err ( where_bounds )  =>  return   Ok ( ( self . bail_with_ambiguity ( & where_bounds) ,  None ) ) , 
1385+             } 
13871386        } 
13881387
1389-         if  candidates. iter ( ) . any ( |c| matches ! ( c. source,  CandidateSource :: AliasBound ) )  { 
1388+         if  candidates. applicable . iter ( ) . any ( |c| matches ! ( c. source,  CandidateSource :: AliasBound ) )  { 
13901389            let  alias_bounds:  Vec < _ >  = candidates
1391-                 . iter ( ) 
1392-                 . filter ( |c| matches ! ( c. source,  CandidateSource :: AliasBound ) ) 
1393-                 . map ( |c| c. result ) 
1390+                 . applicable 
1391+                 . extract_if ( ..,  |c| matches ! ( c. source,  CandidateSource :: AliasBound ) ) 
13941392                . collect ( ) ; 
1395-             return  if  let  Some ( response)  = self . try_merge_responses ( & alias_bounds)  { 
1396-                 Ok ( ( response,  Some ( TraitGoalProvenVia :: AliasBound ) ) ) 
1397-             }  else  { 
1398-                 Ok ( ( self . bail_with_ambiguity ( & alias_bounds) ,  None ) ) 
1399-             } ; 
1393+             match  self . try_merge_candidates ( alias_bounds,  vec ! [ ] )  { 
1394+                 Ok ( response)  => return  Ok ( ( response,  Some ( TraitGoalProvenVia :: AliasBound ) ) ) , 
1395+                 Err ( alias_bounds)  => return  Ok ( ( self . bail_with_ambiguity ( & alias_bounds) ,  None ) ) , 
1396+             } 
14001397        } 
14011398
1402-         self . filter_specialized_impls ( AllowInferenceConstraints :: No ,  & mut  candidates) ; 
1403-         self . unsound_prefer_builtin_dyn_impl ( & mut  candidates) ; 
1399+         self . filter_specialized_impls ( AllowInferenceConstraints :: No ,  & mut  candidates. applicable ) ; 
1400+         self . unsound_prefer_builtin_dyn_impl ( & mut  candidates. applicable ) ; 
14041401
14051402        // If there are *only* global where bounds, then make sure to return that this 
14061403        // is still reported as being proven-via the param-env so that rigid projections 
14071404        // operate correctly. Otherwise, drop all global where-bounds before merging the 
14081405        // remaining candidates. 
14091406        let  proven_via = if  candidates
1407+             . applicable 
14101408            . iter ( ) 
14111409            . all ( |c| matches ! ( c. source,  CandidateSource :: ParamEnv ( ParamEnvSource :: Global ) ) ) 
14121410        { 
14131411            TraitGoalProvenVia :: ParamEnv 
14141412        }  else  { 
14151413            candidates
1414+                 . applicable 
14161415                . retain ( |c| !matches ! ( c. source,  CandidateSource :: ParamEnv ( ParamEnvSource :: Global ) ) ) ; 
14171416            TraitGoalProvenVia :: Misc 
14181417        } ; 
14191418
1420-         let  all_candidates:  Vec < _ >  = candidates. into_iter ( ) . map ( |c| c. result ) . collect ( ) ; 
1421-         if  let  Some ( response)  = self . try_merge_responses ( & all_candidates)  { 
1422-             Ok ( ( response,  Some ( proven_via) ) ) 
1423-         }  else  { 
1424-             self . flounder ( & all_candidates) . map ( |r| ( r,  None ) ) 
1419+         match  self . try_merge_candidates ( candidates. applicable ,  vec ! [ ] )  { 
1420+             Ok ( response)  => Ok ( ( response,  Some ( proven_via) ) ) , 
1421+             Err ( candidates)  => self . flounder ( & candidates) . map ( |r| ( r,  None ) ) , 
14251422        } 
14261423    } 
14271424
0 commit comments