@@ -10,6 +10,7 @@ use rustc_hir_analysis::hir_ty_lowering::{
1010 GenericArgsLowerer , HirTyLowerer , IsMethodCall , RegionInferReason ,
1111} ;
1212use rustc_infer:: infer:: { self , DefineOpaqueTypes , InferOk } ;
13+ use rustc_lint:: builtin:: SUPERTRAIT_ITEM_SHADOWING ;
1314use rustc_middle:: traits:: { ObligationCauseCode , UnifyReceiverContext } ;
1415use rustc_middle:: ty:: adjustment:: {
1516 Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability , PointerCoercion ,
@@ -25,6 +26,9 @@ use rustc_trait_selection::traits;
2526use tracing:: debug;
2627
2728use super :: { MethodCallee , probe} ;
29+ use crate :: errors:: {
30+ SupertraitMethodShadowee , SupertraitMethodShadower , SupertraitMethodShadowing ,
31+ } ;
2832use crate :: { FnCtxt , callee} ;
2933
3034struct ConfirmContext < ' a , ' tcx > {
@@ -144,6 +148,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
144148 // Make sure nobody calls `drop()` explicitly.
145149 self . enforce_illegal_method_limitations ( pick) ;
146150
151+ self . enforce_shadowed_supertrait_methods ( pick, segment) ;
152+
147153 // Add any trait/regions obligations specified on the method's type parameters.
148154 // We won't add these if we encountered an illegal sized bound, so that we can use
149155 // a custom error in that case.
@@ -663,6 +669,45 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
663669 }
664670 }
665671
672+ fn enforce_shadowed_supertrait_methods (
673+ & self ,
674+ pick : & probe:: Pick < ' _ > ,
675+ segment : & hir:: PathSegment < ' tcx > ,
676+ ) {
677+ if pick. shadowed_candidates . is_empty ( ) {
678+ return ;
679+ }
680+
681+ let shadower_span = self . tcx . def_span ( pick. item . def_id ) ;
682+ let subtrait = self . tcx . item_name ( pick. item . trait_container ( self . tcx ) . unwrap ( ) ) ;
683+ let shadower = SupertraitMethodShadower { span : shadower_span, subtrait } ;
684+
685+ let shadowee = if let [ shadowee] = & pick. shadowed_candidates [ ..] {
686+ let shadowee_span = self . tcx . def_span ( shadowee. def_id ) ;
687+ let supertrait = self . tcx . item_name ( shadowee. trait_container ( self . tcx ) . unwrap ( ) ) ;
688+ SupertraitMethodShadowee :: Labeled { span : shadowee_span, supertrait }
689+ } else {
690+ let ( traits, spans) : ( Vec < _ > , Vec < _ > ) = pick
691+ . shadowed_candidates
692+ . iter ( )
693+ . map ( |item| {
694+ (
695+ self . tcx . item_name ( item. trait_container ( self . tcx ) . unwrap ( ) ) ,
696+ self . tcx . def_span ( item. def_id ) ,
697+ )
698+ } )
699+ . unzip ( ) ;
700+ SupertraitMethodShadowee :: Several { traits : traits. into ( ) , spans : spans. into ( ) }
701+ } ;
702+
703+ self . tcx . emit_node_span_lint (
704+ SUPERTRAIT_ITEM_SHADOWING ,
705+ segment. hir_id ,
706+ segment. ident . span ,
707+ SupertraitMethodShadowing { shadower, shadowee, method : segment. ident . name , subtrait } ,
708+ ) ;
709+ }
710+
666711 fn upcast (
667712 & mut self ,
668713 source_trait_ref : ty:: PolyTraitRef < ' tcx > ,
0 commit comments