@@ -19,6 +19,7 @@ use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
1919use rustc_middle:: ty:: { self , Term , Ty , TyCtxt , TypingMode , Upcast } ;
2020use rustc_middle:: { bug, span_bug} ;
2121use rustc_span:: symbol:: sym;
22+ use rustc_type_ir:: elaborate;
2223use tracing:: { debug, instrument} ;
2324
2425use super :: {
@@ -60,7 +61,7 @@ enum ProjectionCandidate<'tcx> {
6061 TraitDef ( ty:: PolyProjectionPredicate < ' tcx > ) ,
6162
6263 /// Bounds specified on an object type
63- Object ( ty:: PolyProjectionPredicate < ' tcx > ) ,
64+ Object ( ty:: PolyProjectionPredicate < ' tcx > , bool ) ,
6465
6566 /// From an "impl" (or a "pseudo-impl" returned by select)
6667 Select ( Selection < ' tcx > ) ,
@@ -683,7 +684,7 @@ fn project<'cx, 'tcx>(
683684
684685 assemble_candidates_from_object_ty ( selcx, obligation, & mut candidates) ;
685686
686- if let ProjectionCandidateSet :: Single ( ProjectionCandidate :: Object ( _ ) ) = candidates {
687+ if let ProjectionCandidateSet :: Single ( ProjectionCandidate :: Object ( .. ) ) = candidates {
687688 // Avoid normalization cycle from selection (see
688689 // `assemble_candidates_from_object_ty`).
689690 // FIXME(lazy_normalization): Lazy normalization should save us from
@@ -839,6 +840,7 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
839840 }
840841 _ => return ,
841842 } ;
843+
842844 let env_predicates = data
843845 . projection_bounds ( )
844846 . filter ( |bound| bound. item_def_id ( ) == obligation. predicate . def_id )
@@ -848,10 +850,30 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
848850 selcx,
849851 obligation,
850852 candidate_set,
851- ProjectionCandidate :: Object ,
853+ |c| ProjectionCandidate :: Object ( c , false ) ,
852854 env_predicates,
853855 false ,
854856 ) ;
857+
858+ let shadowed =
859+ data. projection_bounds ( ) . any ( |bound| bound. item_def_id ( ) == obligation. predicate . def_id ) ;
860+
861+ if !shadowed && let Some ( principal) = data. principal ( ) {
862+ let principal: ty:: Clause < ' tcx > = principal. with_self_ty ( tcx, self_ty) . upcast ( tcx) ;
863+ let supertrait_projections = elaborate:: elaborate ( tcx, [ principal] ) . filter ( |clause| {
864+ clause
865+ . as_projection_clause ( )
866+ . is_some_and ( |proj| proj. projection_def_id ( ) == obligation. predicate . def_id )
867+ } ) ;
868+ assemble_candidates_from_predicates (
869+ selcx,
870+ obligation,
871+ candidate_set,
872+ |c| ProjectionCandidate :: Object ( c, true ) ,
873+ supertrait_projections,
874+ true ,
875+ ) ;
876+ }
855877}
856878
857879#[ instrument(
@@ -1258,10 +1280,12 @@ fn confirm_candidate<'cx, 'tcx>(
12581280) -> Progress < ' tcx > {
12591281 debug ! ( ?obligation, ?candidate, "confirm_candidate" ) ;
12601282 let mut progress = match candidate {
1261- ProjectionCandidate :: ParamEnv ( poly_projection)
1262- | ProjectionCandidate :: Object ( poly_projection) => {
1283+ ProjectionCandidate :: ParamEnv ( poly_projection) => {
12631284 confirm_param_env_candidate ( selcx, obligation, poly_projection, false )
12641285 }
1286+ ProjectionCandidate :: Object ( poly_projection, from_super) => {
1287+ confirm_param_env_candidate ( selcx, obligation, poly_projection, from_super)
1288+ }
12651289
12661290 ProjectionCandidate :: TraitDef ( poly_projection) => {
12671291 confirm_param_env_candidate ( selcx, obligation, poly_projection, true )
0 commit comments