@@ -5,15 +5,16 @@ use std::num::NonZero;
55
66use rustc_ast_lowering:: stability:: extern_abi_stability;
77use rustc_data_structures:: fx:: FxIndexMap ;
8+ use rustc_data_structures:: smallvec:: SmallVec ;
89use rustc_data_structures:: unord:: { ExtendUnord , UnordMap , UnordSet } ;
910use rustc_feature:: { EnabledLangFeature , EnabledLibFeature } ;
1011use rustc_hir:: attrs:: { AttributeKind , DeprecatedSince } ;
11- use rustc_hir:: def:: { DefKind , Res } ;
12- use rustc_hir:: def_id:: { CRATE_DEF_ID , LOCAL_CRATE , LocalDefId , LocalModDefId } ;
12+ use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
13+ use rustc_hir:: def_id:: { CRATE_DEF_ID , DefId , LOCAL_CRATE , LocalDefId , LocalModDefId } ;
1314use rustc_hir:: intravisit:: { self , Visitor , VisitorExt } ;
1415use rustc_hir:: {
15- self as hir, AmbigArg , ConstStability , DefaultBodyStability , FieldDef , Item , ItemKind ,
16- Stability , StabilityLevel , StableSince , TraitRef , Ty , TyKind , UnstableReason ,
16+ self as hir, AmbigArg , ConstStability , DefaultBodyStability , FieldDef , HirId , Item , ItemKind ,
17+ Path , Stability , StabilityLevel , StableSince , TraitRef , Ty , TyKind , UnstableReason , UsePath ,
1718 VERSION_PLACEHOLDER , Variant , find_attr,
1819} ;
1920use rustc_middle:: hir:: nested_filter;
@@ -739,6 +740,38 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
739740 intravisit:: walk_poly_trait_ref ( self , t) ;
740741 }
741742
743+ fn visit_use ( & mut self , path : & ' tcx UsePath < ' tcx > , hir_id : HirId ) {
744+ let UsePath { segments, ref res, span } = * path;
745+
746+ // At most 3 (since there are 3 namespaces) so don't bother with
747+ // a set, or allocating a vec.
748+ let mut seen_dids = SmallVec :: < [ DefId ; 3 ] > :: new ( ) ;
749+
750+ for res in res. present_items ( ) {
751+ // A use item can import something from two namespaces at the same time.
752+ // For deprecation/stability we don't want to warn twice.
753+ // This specifically happens with constructors for unit/tuple structs.
754+ if let Some ( did) = res. opt_def_id ( ) {
755+ // If it's a ctor, we need the parent did.
756+ // The parent defid of a constructor is that of the struct it constructs.
757+ let did = match self . tcx . def_kind ( did) {
758+ DefKind :: Ctor ( CtorOf :: Struct , _) => self . tcx . parent ( did) ,
759+ _ => did,
760+ } ;
761+
762+ // When we've already seen a defid, don't walk this path.
763+ // This avoids the duplicate deprecation warnings.
764+ if seen_dids. contains ( & did) {
765+ continue ;
766+ }
767+
768+ seen_dids. push ( did) ;
769+ }
770+
771+ self . visit_path ( & Path { segments, res, span } , hir_id) ;
772+ }
773+ }
774+
742775 fn visit_path ( & mut self , path : & hir:: Path < ' tcx > , id : hir:: HirId ) {
743776 if let Some ( def_id) = path. res . opt_def_id ( ) {
744777 let method_span = path. segments . last ( ) . map ( |s| s. ident . span ) ;
0 commit comments