@@ -10,6 +10,7 @@ use rustc_hir_analysis::hir_ty_lowering::{
10
10
FeedConstTy , GenericArgsLowerer , HirTyLowerer , IsMethodCall , RegionInferReason ,
11
11
} ;
12
12
use rustc_infer:: infer:: { self , DefineOpaqueTypes , InferOk } ;
13
+ use rustc_lint:: builtin:: SUPERTRAIT_ITEM_SHADOWING_USAGE ;
13
14
use rustc_middle:: traits:: { ObligationCauseCode , UnifyReceiverContext } ;
14
15
use rustc_middle:: ty:: adjustment:: {
15
16
Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability , PointerCoercion ,
@@ -24,6 +25,7 @@ use rustc_trait_selection::traits;
24
25
use tracing:: debug;
25
26
26
27
use super :: { MethodCallee , probe} ;
28
+ use crate :: errors:: { SupertraitItemShadowee , SupertraitItemShadower , SupertraitItemShadowing } ;
27
29
use crate :: { FnCtxt , callee} ;
28
30
29
31
struct ConfirmContext < ' a , ' tcx > {
@@ -141,7 +143,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
141
143
let method_sig = ty:: Binder :: dummy ( method_sig) ;
142
144
143
145
// Make sure nobody calls `drop()` explicitly.
144
- self . enforce_illegal_method_limitations ( pick) ;
146
+ self . check_for_illegal_method_calls ( pick) ;
147
+
148
+ // Lint when an item is shadowing a supertrait item.
149
+ self . lint_shadowed_supertrait_items ( pick, segment) ;
145
150
146
151
// Add any trait/regions obligations specified on the method's type parameters.
147
152
// We won't add these if we encountered an illegal sized bound, so that we can use
@@ -656,7 +661,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
656
661
} )
657
662
}
658
663
659
- fn enforce_illegal_method_limitations ( & self , pick : & probe:: Pick < ' _ > ) {
664
+ fn check_for_illegal_method_calls ( & self , pick : & probe:: Pick < ' _ > ) {
660
665
// Disallow calls to the method `drop` defined in the `Drop` trait.
661
666
if let Some ( trait_def_id) = pick. item . trait_container ( self . tcx ) {
662
667
if let Err ( e) = callee:: check_legal_trait_for_method_call (
@@ -672,6 +677,45 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
672
677
}
673
678
}
674
679
680
+ fn lint_shadowed_supertrait_items (
681
+ & self ,
682
+ pick : & probe:: Pick < ' _ > ,
683
+ segment : & hir:: PathSegment < ' tcx > ,
684
+ ) {
685
+ if pick. shadowed_candidates . is_empty ( ) {
686
+ return ;
687
+ }
688
+
689
+ let shadower_span = self . tcx . def_span ( pick. item . def_id ) ;
690
+ let subtrait = self . tcx . item_name ( pick. item . trait_container ( self . tcx ) . unwrap ( ) ) ;
691
+ let shadower = SupertraitItemShadower { span : shadower_span, subtrait } ;
692
+
693
+ let shadowee = if let [ shadowee] = & pick. shadowed_candidates [ ..] {
694
+ let shadowee_span = self . tcx . def_span ( shadowee. def_id ) ;
695
+ let supertrait = self . tcx . item_name ( shadowee. trait_container ( self . tcx ) . unwrap ( ) ) ;
696
+ SupertraitItemShadowee :: Labeled { span : shadowee_span, supertrait }
697
+ } else {
698
+ let ( traits, spans) : ( Vec < _ > , Vec < _ > ) = pick
699
+ . shadowed_candidates
700
+ . iter ( )
701
+ . map ( |item| {
702
+ (
703
+ self . tcx . item_name ( item. trait_container ( self . tcx ) . unwrap ( ) ) ,
704
+ self . tcx . def_span ( item. def_id ) ,
705
+ )
706
+ } )
707
+ . unzip ( ) ;
708
+ SupertraitItemShadowee :: Several { traits : traits. into ( ) , spans : spans. into ( ) }
709
+ } ;
710
+
711
+ self . tcx . emit_node_span_lint (
712
+ SUPERTRAIT_ITEM_SHADOWING_USAGE ,
713
+ segment. hir_id ,
714
+ segment. ident . span ,
715
+ SupertraitItemShadowing { shadower, shadowee, item : segment. ident . name , subtrait } ,
716
+ ) ;
717
+ }
718
+
675
719
fn upcast (
676
720
& mut self ,
677
721
source_trait_ref : ty:: PolyTraitRef < ' tcx > ,
0 commit comments