@@ -18,6 +18,7 @@ use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
1818use rustc_middle:: ty:: { self , Term , Ty , TyCtxt , TypingMode , Upcast } ;
1919use rustc_middle:: { bug, span_bug} ;
2020use rustc_span:: symbol:: sym;
21+ use rustc_type_ir:: elaborate;
2122use tracing:: { debug, instrument} ;
2223
2324use super :: {
@@ -59,7 +60,7 @@ enum ProjectionCandidate<'tcx> {
5960 TraitDef ( ty:: PolyProjectionPredicate < ' tcx > ) ,
6061
6162 /// Bounds specified on an object type
62- Object ( ty:: PolyProjectionPredicate < ' tcx > ) ,
63+ Object ( ty:: PolyProjectionPredicate < ' tcx > , bool ) ,
6364
6465 /// From an "impl" (or a "pseudo-impl" returned by select)
6566 Select ( Selection < ' tcx > ) ,
@@ -682,7 +683,7 @@ fn project<'cx, 'tcx>(
682683
683684 assemble_candidates_from_object_ty ( selcx, obligation, & mut candidates) ;
684685
685- if let ProjectionCandidateSet :: Single ( ProjectionCandidate :: Object ( _ ) ) = candidates {
686+ if let ProjectionCandidateSet :: Single ( ProjectionCandidate :: Object ( .. ) ) = candidates {
686687 // Avoid normalization cycle from selection (see
687688 // `assemble_candidates_from_object_ty`).
688689 // FIXME(lazy_normalization): Lazy normalization should save us from
@@ -838,6 +839,7 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
838839 }
839840 _ => return ,
840841 } ;
842+
841843 let env_predicates = data
842844 . projection_bounds ( )
843845 . filter ( |bound| bound. item_def_id ( ) == obligation. predicate . def_id )
@@ -847,10 +849,30 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
847849 selcx,
848850 obligation,
849851 candidate_set,
850- ProjectionCandidate :: Object ,
852+ |c| ProjectionCandidate :: Object ( c , false ) ,
851853 env_predicates,
852854 false ,
853855 ) ;
856+
857+ let shadowed =
858+ data. projection_bounds ( ) . any ( |bound| bound. item_def_id ( ) == obligation. predicate . def_id ) ;
859+
860+ if !shadowed && let Some ( principal) = data. principal ( ) {
861+ let principal: ty:: Clause < ' tcx > = principal. with_self_ty ( tcx, self_ty) . upcast ( tcx) ;
862+ let supertrait_projections = elaborate:: elaborate ( tcx, [ principal] ) . filter ( |clause| {
863+ clause
864+ . as_projection_clause ( )
865+ . is_some_and ( |proj| proj. projection_def_id ( ) == obligation. predicate . def_id )
866+ } ) ;
867+ assemble_candidates_from_predicates (
868+ selcx,
869+ obligation,
870+ candidate_set,
871+ |c| ProjectionCandidate :: Object ( c, true ) ,
872+ supertrait_projections,
873+ true ,
874+ ) ;
875+ }
854876}
855877
856878#[ instrument(
@@ -1259,10 +1281,12 @@ fn confirm_candidate<'cx, 'tcx>(
12591281) -> Progress < ' tcx > {
12601282 debug ! ( ?obligation, ?candidate, "confirm_candidate" ) ;
12611283 let mut progress = match candidate {
1262- ProjectionCandidate :: ParamEnv ( poly_projection)
1263- | ProjectionCandidate :: Object ( poly_projection) => {
1284+ ProjectionCandidate :: ParamEnv ( poly_projection) => {
12641285 confirm_param_env_candidate ( selcx, obligation, poly_projection, false )
12651286 }
1287+ ProjectionCandidate :: Object ( poly_projection, from_super) => {
1288+ confirm_param_env_candidate ( selcx, obligation, poly_projection, from_super)
1289+ }
12661290
12671291 ProjectionCandidate :: TraitDef ( poly_projection) => {
12681292 confirm_param_env_candidate ( selcx, obligation, poly_projection, true )
0 commit comments