@@ -792,37 +792,46 @@ where
792
792
} ;
793
793
794
794
match proven_via {
795
- // Even when a trait bound has been proven using a where-bound, we
796
- // still need to consider alias-bounds for normalization, see
797
- // tests/ui/next-solver/alias-bound-shadowed-by-env.rs.
798
- //
799
- // FIXME(const_trait_impl): should this behavior also be used by
800
- // constness checking. Doing so is *at least theoretically* breaking,
801
- // see github.com/rust-lang/rust/issues/133044#issuecomment-2500709754
802
795
TraitGoalProvenVia :: ParamEnv | TraitGoalProvenVia :: AliasBound => {
803
- let mut candidates_from_env_and_bounds: Vec < _ > = candidates
804
- . iter ( )
805
- . filter ( |c| {
806
- matches ! (
807
- c. source,
808
- CandidateSource :: AliasBound | CandidateSource :: ParamEnv ( _)
809
- )
810
- } )
811
- . map ( |c| c. result )
812
- . collect ( ) ;
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
+ // Even when a trait bound has been proven using a where-bound, we
805
+ // still need to consider alias-bounds for normalization, see
806
+ // tests/ui/next-solver/alias-bound-shadowed-by-env.rs.
807
+ //
808
+ // 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
+ }
813
822
814
823
// If the trait goal has been proven by using the environment, we want to treat
815
824
// aliases as rigid if there are no applicable projection bounds in the environment.
816
- if candidates_from_env_and_bounds . is_empty ( ) {
825
+ if considered_candidates . is_empty ( ) {
817
826
if let Ok ( response) = inject_normalize_to_rigid_candidate ( self ) {
818
- candidates_from_env_and_bounds . push ( response) ;
827
+ considered_candidates . push ( response) ;
819
828
}
820
829
}
821
830
822
- if let Some ( response) = self . try_merge_responses ( & candidates_from_env_and_bounds ) {
831
+ if let Some ( response) = self . try_merge_responses ( & considered_candidates ) {
823
832
Ok ( response)
824
833
} else {
825
- self . flounder ( & candidates_from_env_and_bounds )
834
+ self . flounder ( & considered_candidates )
826
835
}
827
836
}
828
837
TraitGoalProvenVia :: Misc => {
0 commit comments