@@ -12,6 +12,7 @@ use rustc_hir::lang_items::LangItem;
1212use rustc_hir:: { AmbigArg , ItemKind } ;
1313use rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ;
1414use rustc_infer:: infer:: { self , InferCtxt , TyCtxtInferExt } ;
15+ use rustc_lint_defs:: builtin:: SUPERTRAIT_ITEM_SHADOWING_DEFINITION ;
1516use rustc_macros:: LintDiagnostic ;
1617use rustc_middle:: mir:: interpret:: ErrorHandled ;
1718use rustc_middle:: query:: Providers ;
@@ -388,7 +389,12 @@ fn check_trait_item<'tcx>(
388389 hir:: TraitItemKind :: Type ( _bounds, Some ( ty) ) => ( None , ty. span ) ,
389390 _ => ( None , trait_item. span ) ,
390391 } ;
392+
391393 check_dyn_incompatible_self_trait_by_name ( tcx, trait_item) ;
394+
395+ // Check that an item definition in a subtrait is shadowing a supertrait item.
396+ lint_item_shadowing_supertrait_item ( tcx, def_id) ;
397+
392398 let mut res = check_associated_item ( tcx, def_id, span, method_sig) ;
393399
394400 if matches ! ( trait_item. kind, hir:: TraitItemKind :: Fn ( ..) ) {
@@ -898,6 +904,45 @@ fn check_dyn_incompatible_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitI
898904 }
899905}
900906
907+ fn lint_item_shadowing_supertrait_item < ' tcx > ( tcx : TyCtxt < ' tcx > , trait_item_def_id : LocalDefId ) {
908+ let item_name = tcx. item_name ( trait_item_def_id. to_def_id ( ) ) ;
909+ let trait_def_id = tcx. local_parent ( trait_item_def_id) ;
910+
911+ let shadowed: Vec < _ > = traits:: supertrait_def_ids ( tcx, trait_def_id. to_def_id ( ) )
912+ . skip ( 1 )
913+ . flat_map ( |supertrait_def_id| {
914+ tcx. associated_items ( supertrait_def_id) . filter_by_name_unhygienic ( item_name)
915+ } )
916+ . collect ( ) ;
917+ if !shadowed. is_empty ( ) {
918+ let shadowee = if let [ shadowed] = shadowed[ ..] {
919+ errors:: SupertraitItemShadowee :: Labeled {
920+ span : tcx. def_span ( shadowed. def_id ) ,
921+ supertrait : tcx. item_name ( shadowed. trait_container ( tcx) . unwrap ( ) ) ,
922+ }
923+ } else {
924+ let ( traits, spans) : ( Vec < _ > , Vec < _ > ) = shadowed
925+ . iter ( )
926+ . map ( |item| {
927+ ( tcx. item_name ( item. trait_container ( tcx) . unwrap ( ) ) , tcx. def_span ( item. def_id ) )
928+ } )
929+ . unzip ( ) ;
930+ errors:: SupertraitItemShadowee :: Several { traits : traits. into ( ) , spans : spans. into ( ) }
931+ } ;
932+
933+ tcx. emit_node_span_lint (
934+ SUPERTRAIT_ITEM_SHADOWING_DEFINITION ,
935+ tcx. local_def_id_to_hir_id ( trait_item_def_id) ,
936+ tcx. def_span ( trait_item_def_id) ,
937+ errors:: SupertraitItemShadowing {
938+ item : item_name,
939+ subtrait : tcx. item_name ( trait_def_id. to_def_id ( ) ) ,
940+ shadowee,
941+ } ,
942+ ) ;
943+ }
944+ }
945+
901946fn check_impl_item < ' tcx > (
902947 tcx : TyCtxt < ' tcx > ,
903948 impl_item : & ' tcx hir:: ImplItem < ' tcx > ,
0 commit comments