@@ -791,7 +791,7 @@ where
791
791
return Ok ( self . make_ambiguous_response_no_constraints ( MaybeCause :: Ambiguity ) ) ;
792
792
} ;
793
793
794
- let responses : Vec < _ > = match proven_via {
794
+ match proven_via {
795
795
// Even when a trait bound has been proven using a where-bound, we
796
796
// still need to consider alias-bounds for normalization, see
797
797
// tests/ui/next-solver/alias-bound-shadowed-by-env.rs.
@@ -800,7 +800,7 @@ where
800
800
// constness checking. Doing so is *at least theoretically* breaking,
801
801
// see github.com/rust-lang/rust/issues/133044#issuecomment-2500709754
802
802
TraitGoalProvenVia :: ParamEnv | TraitGoalProvenVia :: AliasBound => {
803
- let mut candidates_from_env : Vec < _ > = candidates
803
+ let mut candidates_from_env_and_bounds : Vec < _ > = candidates
804
804
. iter ( )
805
805
. filter ( |c| {
806
806
matches ! (
@@ -813,16 +813,37 @@ where
813
813
814
814
// If the trait goal has been proven by using the environment, we want to treat
815
815
// aliases as rigid if there are no applicable projection bounds in the environment.
816
- if candidates_from_env . is_empty ( ) {
816
+ if candidates_from_env_and_bounds . is_empty ( ) {
817
817
if let Ok ( response) = inject_normalize_to_rigid_candidate ( self ) {
818
- candidates_from_env . push ( response) ;
818
+ candidates_from_env_and_bounds . push ( response) ;
819
819
}
820
820
}
821
- candidates_from_env
821
+
822
+ if let Some ( response) = self . try_merge_responses ( & candidates_from_env_and_bounds) {
823
+ Ok ( response)
824
+ } else {
825
+ self . flounder ( & candidates_from_env_and_bounds)
826
+ }
822
827
}
823
- TraitGoalProvenVia :: Misc => candidates. iter ( ) . map ( |c| c. result ) . collect ( ) ,
824
- } ;
828
+ TraitGoalProvenVia :: Misc => {
829
+ // Prefer "orphaned" param-env normalization predicates, which are used
830
+ // (for example, and ideally only) when proving item bounds for an impl.
831
+ let candidates_from_env: Vec < _ > = candidates
832
+ . iter ( )
833
+ . filter ( |c| matches ! ( c. source, CandidateSource :: ParamEnv ( _) ) )
834
+ . map ( |c| c. result )
835
+ . collect ( ) ;
836
+ if let Some ( response) = self . try_merge_responses ( & candidates_from_env) {
837
+ return Ok ( response) ;
838
+ }
825
839
826
- self . try_merge_responses ( & responses) . map_or_else ( || self . flounder ( & responses) , Ok )
840
+ let responses: Vec < _ > = candidates. iter ( ) . map ( |c| c. result ) . collect ( ) ;
841
+ if let Some ( response) = self . try_merge_responses ( & responses) {
842
+ Ok ( response)
843
+ } else {
844
+ self . flounder ( & responses)
845
+ }
846
+ }
847
+ }
827
848
}
828
849
}
0 commit comments