@@ -10,6 +10,7 @@ use rustc_hir_analysis::hir_ty_lowering::{
10
10
GenericArgsLowerer , HirTyLowerer , IsMethodCall , RegionInferReason ,
11
11
} ;
12
12
use rustc_infer:: infer:: { self , DefineOpaqueTypes , InferOk } ;
13
+ use rustc_lint:: builtin:: SUPERTRAIT_ITEM_SHADOWING ;
13
14
use rustc_middle:: traits:: { ObligationCauseCode , UnifyReceiverContext } ;
14
15
use rustc_middle:: ty:: adjustment:: {
15
16
Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability , PointerCoercion ,
@@ -25,6 +26,9 @@ use rustc_trait_selection::traits;
25
26
use tracing:: debug;
26
27
27
28
use super :: { MethodCallee , probe} ;
29
+ use crate :: errors:: {
30
+ SupertraitMethodShadowee , SupertraitMethodShadower , SupertraitMethodShadowing ,
31
+ } ;
28
32
use crate :: { FnCtxt , callee} ;
29
33
30
34
struct ConfirmContext < ' a , ' tcx > {
@@ -144,6 +148,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
144
148
// Make sure nobody calls `drop()` explicitly.
145
149
self . enforce_illegal_method_limitations ( pick) ;
146
150
151
+ self . enforce_shadowed_supertrait_methods ( pick, segment) ;
152
+
147
153
// Add any trait/regions obligations specified on the method's type parameters.
148
154
// We won't add these if we encountered an illegal sized bound, so that we can use
149
155
// a custom error in that case.
@@ -664,6 +670,45 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
664
670
}
665
671
}
666
672
673
+ fn enforce_shadowed_supertrait_methods (
674
+ & self ,
675
+ pick : & probe:: Pick < ' _ > ,
676
+ segment : & hir:: PathSegment < ' tcx > ,
677
+ ) {
678
+ if pick. shadowed_candidates . is_empty ( ) {
679
+ return ;
680
+ }
681
+
682
+ let shadower_span = self . tcx . def_span ( pick. item . def_id ) ;
683
+ let subtrait = self . tcx . item_name ( pick. item . trait_container ( self . tcx ) . unwrap ( ) ) ;
684
+ let shadower = SupertraitMethodShadower { span : shadower_span, subtrait } ;
685
+
686
+ let shadowee = if let [ shadowee] = & pick. shadowed_candidates [ ..] {
687
+ let shadowee_span = self . tcx . def_span ( shadowee. def_id ) ;
688
+ let supertrait = self . tcx . item_name ( shadowee. trait_container ( self . tcx ) . unwrap ( ) ) ;
689
+ SupertraitMethodShadowee :: Labeled { span : shadowee_span, supertrait }
690
+ } else {
691
+ let ( traits, spans) : ( Vec < _ > , Vec < _ > ) = pick
692
+ . shadowed_candidates
693
+ . iter ( )
694
+ . map ( |item| {
695
+ (
696
+ self . tcx . item_name ( item. trait_container ( self . tcx ) . unwrap ( ) ) ,
697
+ self . tcx . def_span ( item. def_id ) ,
698
+ )
699
+ } )
700
+ . unzip ( ) ;
701
+ SupertraitMethodShadowee :: Several { traits : traits. into ( ) , spans : spans. into ( ) }
702
+ } ;
703
+
704
+ self . tcx . emit_node_span_lint (
705
+ SUPERTRAIT_ITEM_SHADOWING ,
706
+ segment. hir_id ,
707
+ segment. ident . span ,
708
+ SupertraitMethodShadowing { shadower, shadowee, method : segment. ident . name , subtrait } ,
709
+ ) ;
710
+ }
711
+
667
712
fn upcast (
668
713
& mut self ,
669
714
source_trait_ref : ty:: PolyTraitRef < ' tcx > ,
0 commit comments