@@ -10,6 +10,7 @@ use rustc_hir_analysis::hir_ty_lowering::{
1010 FeedConstTy , GenericArgsLowerer , HirTyLowerer , IsMethodCall , RegionInferReason ,
1111} ;
1212use rustc_infer:: infer:: { self , DefineOpaqueTypes , InferOk } ;
13+ use rustc_lint:: builtin:: SUPERTRAIT_ITEM_SHADOWING_USAGE ;
1314use rustc_middle:: traits:: { ObligationCauseCode , UnifyReceiverContext } ;
1415use rustc_middle:: ty:: adjustment:: {
1516 Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability , PointerCoercion ,
@@ -24,6 +25,7 @@ use rustc_trait_selection::traits;
2425use tracing:: debug;
2526
2627use super :: { MethodCallee , probe} ;
28+ use crate :: errors:: { SupertraitItemShadowee , SupertraitItemShadower , SupertraitItemShadowing } ;
2729use crate :: { FnCtxt , callee} ;
2830
2931struct ConfirmContext < ' a , ' tcx > {
@@ -143,6 +145,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
143145 // Make sure nobody calls `drop()` explicitly.
144146 self . enforce_illegal_method_limitations ( pick) ;
145147
148+ self . enforce_shadowed_supertrait_items ( pick, segment) ;
149+
146150 // Add any trait/regions obligations specified on the method's type parameters.
147151 // We won't add these if we encountered an illegal sized bound, so that we can use
148152 // a custom error in that case.
@@ -672,6 +676,45 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
672676 }
673677 }
674678
679+ fn enforce_shadowed_supertrait_items (
680+ & self ,
681+ pick : & probe:: Pick < ' _ > ,
682+ segment : & hir:: PathSegment < ' tcx > ,
683+ ) {
684+ if pick. shadowed_candidates . is_empty ( ) {
685+ return ;
686+ }
687+
688+ let shadower_span = self . tcx . def_span ( pick. item . def_id ) ;
689+ let subtrait = self . tcx . item_name ( pick. item . trait_container ( self . tcx ) . unwrap ( ) ) ;
690+ let shadower = SupertraitItemShadower { span : shadower_span, subtrait } ;
691+
692+ let shadowee = if let [ shadowee] = & pick. shadowed_candidates [ ..] {
693+ let shadowee_span = self . tcx . def_span ( shadowee. def_id ) ;
694+ let supertrait = self . tcx . item_name ( shadowee. trait_container ( self . tcx ) . unwrap ( ) ) ;
695+ SupertraitItemShadowee :: Labeled { span : shadowee_span, supertrait }
696+ } else {
697+ let ( traits, spans) : ( Vec < _ > , Vec < _ > ) = pick
698+ . shadowed_candidates
699+ . iter ( )
700+ . map ( |item| {
701+ (
702+ self . tcx . item_name ( item. trait_container ( self . tcx ) . unwrap ( ) ) ,
703+ self . tcx . def_span ( item. def_id ) ,
704+ )
705+ } )
706+ . unzip ( ) ;
707+ SupertraitItemShadowee :: Several { traits : traits. into ( ) , spans : spans. into ( ) }
708+ } ;
709+
710+ self . tcx . emit_node_span_lint (
711+ SUPERTRAIT_ITEM_SHADOWING_USAGE ,
712+ segment. hir_id ,
713+ segment. ident . span ,
714+ SupertraitItemShadowing { shadower, shadowee, item : segment. ident . name , subtrait } ,
715+ ) ;
716+ }
717+
675718 fn upcast (
676719 & mut self ,
677720 source_trait_ref : ty:: PolyTraitRef < ' tcx > ,
0 commit comments