@@ -289,9 +289,10 @@ where
289
289
D : SolverDelegate < Interner = I > ,
290
290
I : Interner ,
291
291
{
292
- pub ( super ) fn assemble_and_evaluate_candidates < G : GoalKind < D > > (
292
+ fn assemble_and_evaluate_candidates_with_normalized_goal < G : GoalKind < D > > (
293
293
& mut self ,
294
294
goal : Goal < I , G > ,
295
+ assemble : impl FnOnce ( & mut Self , Goal < I , G > ) -> Vec < Candidate < I > > ,
295
296
) -> Vec < Candidate < I > > {
296
297
let Ok ( normalized_self_ty) =
297
298
self . structurally_normalize_ty ( goal. param_env , goal. predicate . self_ty ( ) )
@@ -310,25 +311,40 @@ where
310
311
// normalizing the self type as well, since type variables are not uniquified.
311
312
let goal = self . resolve_vars_if_possible ( goal) ;
312
313
313
- let mut candidates = vec ! [ ] ;
314
-
315
314
if let TypingMode :: Coherence = self . typing_mode ( ) {
316
315
if let Ok ( candidate) = self . consider_coherence_unknowable_candidate ( goal) {
317
316
return vec ! [ candidate] ;
318
317
}
319
318
}
320
319
321
- self . assemble_impl_candidates ( goal, & mut candidates) ;
322
-
323
- self . assemble_builtin_impl_candidates ( goal, & mut candidates) ;
324
-
325
- self . assemble_alias_bound_candidates ( goal, & mut candidates) ;
326
-
327
- self . assemble_object_bound_candidates ( goal, & mut candidates) ;
320
+ assemble ( self , goal)
321
+ }
328
322
329
- self . assemble_param_env_candidates ( goal, & mut candidates) ;
323
+ pub ( super ) fn assemble_and_evaluate_candidates_from_env_and_bounds < G : GoalKind < D > > (
324
+ & mut self ,
325
+ goal : Goal < I , G > ,
326
+ ) -> Vec < Candidate < I > > {
327
+ self . assemble_and_evaluate_candidates_with_normalized_goal ( goal, |ecx, goal| {
328
+ let mut candidates = vec ! [ ] ;
329
+ ecx. assemble_alias_bound_candidates ( goal, & mut candidates) ;
330
+ ecx. assemble_param_env_candidates ( goal, & mut candidates) ;
331
+ candidates
332
+ } )
333
+ }
330
334
331
- candidates
335
+ pub ( super ) fn assemble_and_evaluate_candidates < G : GoalKind < D > > (
336
+ & mut self ,
337
+ goal : Goal < I , G > ,
338
+ ) -> Vec < Candidate < I > > {
339
+ self . assemble_and_evaluate_candidates_with_normalized_goal ( goal, |ecx, goal| {
340
+ let mut candidates = vec ! [ ] ;
341
+ ecx. assemble_impl_candidates ( goal, & mut candidates) ;
342
+ ecx. assemble_builtin_impl_candidates ( goal, & mut candidates) ;
343
+ ecx. assemble_object_bound_candidates ( goal, & mut candidates) ;
344
+ ecx. assemble_alias_bound_candidates ( goal, & mut candidates) ;
345
+ ecx. assemble_param_env_candidates ( goal, & mut candidates) ;
346
+ candidates
347
+ } )
332
348
}
333
349
334
350
pub ( super ) fn forced_ambiguity (
@@ -778,10 +794,10 @@ where
778
794
///
779
795
/// See trait-system-refactor-initiative#124 for more details.
780
796
#[ instrument( level = "debug" , skip( self , inject_normalize_to_rigid_candidate) , ret) ]
781
- pub ( super ) fn merge_candidates (
797
+ pub ( super ) fn assemble_and_merge_candidates < G : GoalKind < D > > (
782
798
& mut self ,
783
799
proven_via : Option < TraitGoalProvenVia > ,
784
- candidates : Vec < Candidate < I > > ,
800
+ goal : Goal < I , G > ,
785
801
inject_normalize_to_rigid_candidate : impl FnOnce ( & mut EvalCtxt < ' _ , D > ) -> QueryResult < I > ,
786
802
) -> QueryResult < I > {
787
803
let Some ( proven_via) = proven_via else {
@@ -793,32 +809,31 @@ where
793
809
794
810
match proven_via {
795
811
TraitGoalProvenVia :: ParamEnv | TraitGoalProvenVia :: AliasBound => {
796
- let mut considered_candidates = Vec :: new ( ) ;
797
- considered_candidates. extend (
798
- candidates
799
- . iter ( )
800
- . filter ( |c| matches ! ( c. source, CandidateSource :: ParamEnv ( _) ) )
801
- . map ( |c| c. result ) ,
802
- ) ;
803
-
804
812
// Even when a trait bound has been proven using a where-bound, we
805
813
// still need to consider alias-bounds for normalization, see
806
- // tests/ui/next-solver/alias-bound-shadowed-by-env.rs.
807
- //
814
+ // `tests/ui/next-solver/alias-bound-shadowed-by-env.rs`.
815
+ let candidates_from_env_and_bounds: Vec < _ > =
816
+ self . assemble_and_evaluate_candidates_from_env_and_bounds ( goal) ;
817
+
818
+ debug_assert ! ( candidates_from_env_and_bounds. iter( ) . all( |c| matches!(
819
+ c. source,
820
+ CandidateSource :: AliasBound | CandidateSource :: ParamEnv ( _)
821
+ ) ) ) ;
822
+
808
823
// We still need to prefer where-bounds over alias-bounds however.
809
- // See tests/ui/winnowing/norm-where-bound-gt-alias-bound.rs.
810
- //
811
- // FIXME(const_trait_impl): should this behavior also be used by
812
- // constness checking. Doing so is *at least theoretically* breaking,
813
- // see github.com/rust-lang/rust/issues/133044#issuecomment-2500709754
814
- if considered_candidates . is_empty ( ) {
815
- considered_candidates . extend (
816
- candidates
817
- . iter ( )
818
- . filter ( |c| matches ! ( c . source , CandidateSource :: AliasBound ) )
819
- . map ( |c| c . result ) ,
820
- ) ;
821
- }
824
+ // See ` tests/ui/winnowing/norm-where-bound-gt-alias-bound.rs` .
825
+ let mut considered_candidates : Vec < _ > = if candidates_from_env_and_bounds
826
+ . iter ( )
827
+ . any ( |c| matches ! ( c . source , CandidateSource :: ParamEnv ( _ ) ) )
828
+ {
829
+ candidates_from_env_and_bounds
830
+ . into_iter ( )
831
+ . filter ( |c| matches ! ( c . source , CandidateSource :: ParamEnv ( _ ) ) )
832
+ . map ( |c| c . result )
833
+ . collect ( )
834
+ } else {
835
+ candidates_from_env_and_bounds . into_iter ( ) . map ( |c| c . result ) . collect ( )
836
+ } ;
822
837
823
838
// If the trait goal has been proven by using the environment, we want to treat
824
839
// aliases as rigid if there are no applicable projection bounds in the environment.
@@ -835,6 +850,8 @@ where
835
850
}
836
851
}
837
852
TraitGoalProvenVia :: Misc => {
853
+ let candidates = self . assemble_and_evaluate_candidates ( goal) ;
854
+
838
855
// Prefer "orphaned" param-env normalization predicates, which are used
839
856
// (for example, and ideally only) when proving item bounds for an impl.
840
857
let candidates_from_env: Vec < _ > = candidates
0 commit comments