@@ -19,6 +19,7 @@ use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
19
19
use rustc_middle:: ty:: { self , Term , Ty , TyCtxt , TypingMode , Upcast } ;
20
20
use rustc_middle:: { bug, span_bug} ;
21
21
use rustc_span:: symbol:: sym;
22
+ use rustc_type_ir:: elaborate;
22
23
use tracing:: { debug, instrument} ;
23
24
24
25
use super :: {
@@ -60,7 +61,7 @@ enum ProjectionCandidate<'tcx> {
60
61
TraitDef ( ty:: PolyProjectionPredicate < ' tcx > ) ,
61
62
62
63
/// Bounds specified on an object type
63
- Object ( ty:: PolyProjectionPredicate < ' tcx > ) ,
64
+ Object ( ty:: PolyProjectionPredicate < ' tcx > , bool ) ,
64
65
65
66
/// From an "impl" (or a "pseudo-impl" returned by select)
66
67
Select ( Selection < ' tcx > ) ,
@@ -683,7 +684,7 @@ fn project<'cx, 'tcx>(
683
684
684
685
assemble_candidates_from_object_ty ( selcx, obligation, & mut candidates) ;
685
686
686
- if let ProjectionCandidateSet :: Single ( ProjectionCandidate :: Object ( _ ) ) = candidates {
687
+ if let ProjectionCandidateSet :: Single ( ProjectionCandidate :: Object ( .. ) ) = candidates {
687
688
// Avoid normalization cycle from selection (see
688
689
// `assemble_candidates_from_object_ty`).
689
690
// FIXME(lazy_normalization): Lazy normalization should save us from
@@ -839,6 +840,7 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
839
840
}
840
841
_ => return ,
841
842
} ;
843
+
842
844
let env_predicates = data
843
845
. projection_bounds ( )
844
846
. filter ( |bound| bound. item_def_id ( ) == obligation. predicate . def_id )
@@ -848,10 +850,30 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>(
848
850
selcx,
849
851
obligation,
850
852
candidate_set,
851
- ProjectionCandidate :: Object ,
853
+ |c| ProjectionCandidate :: Object ( c , false ) ,
852
854
env_predicates,
853
855
false ,
854
856
) ;
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
+ }
855
877
}
856
878
857
879
#[ instrument(
@@ -1258,10 +1280,12 @@ fn confirm_candidate<'cx, 'tcx>(
1258
1280
) -> Progress < ' tcx > {
1259
1281
debug ! ( ?obligation, ?candidate, "confirm_candidate" ) ;
1260
1282
let mut progress = match candidate {
1261
- ProjectionCandidate :: ParamEnv ( poly_projection)
1262
- | ProjectionCandidate :: Object ( poly_projection) => {
1283
+ ProjectionCandidate :: ParamEnv ( poly_projection) => {
1263
1284
confirm_param_env_candidate ( selcx, obligation, poly_projection, false )
1264
1285
}
1286
+ ProjectionCandidate :: Object ( poly_projection, from_super) => {
1287
+ confirm_param_env_candidate ( selcx, obligation, poly_projection, from_super)
1288
+ }
1265
1289
1266
1290
ProjectionCandidate :: TraitDef ( poly_projection) => {
1267
1291
confirm_param_env_candidate ( selcx, obligation, poly_projection, true )
0 commit comments