about summary refs log tree commit diff
path: root/compiler/rustc_passes/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-08-04 02:04:04 +0000
committerbors <bors@rust-lang.org>2021-08-04 02:04:04 +0000
commitbb744e1e9f1e193014ab3f04bf5e0640dbe4dc63 (patch)
tree461416ac8a4134822855c0abf9f80e1a81c9d3b6 /compiler/rustc_passes/src
parent2b8de6f21286d6dbd7dd692af7da7dc6937861d3 (diff)
parentf921410b1c4e38e234758db6dbbfc8b9c419c5fb (diff)
downloadrust-bb744e1e9f1e193014ab3f04bf5e0640dbe4dc63.tar.gz
rust-bb744e1e9f1e193014ab3f04bf5e0640dbe4dc63.zip
Auto merge of #87568 - petrochenkov:localevel, r=cjgillot
rustc: Replace `HirId`s with `LocalDefId`s in `AccessLevels` tables

and passes using those tables - primarily privacy checking, stability checking and dead code checking.

All these passes work with definitions rather than with arbitrary HIR nodes.
r? `@cjgillot`
cc `@lambinoo` (#87487)
Diffstat (limited to 'compiler/rustc_passes/src')
-rw-r--r--compiler/rustc_passes/src/dead.rs101
-rw-r--r--compiler/rustc_passes/src/reachable.rs6
-rw-r--r--compiler/rustc_passes/src/stability.rs92
3 files changed, 96 insertions, 103 deletions
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index b71ec700f81..4e157b0a574 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -5,7 +5,7 @@
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::{Node, PatKind, TyKind};
@@ -14,16 +14,15 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::middle::privacy;
 use rustc_middle::ty::{self, DefIdTree, TyCtxt};
 use rustc_session::lint;
-
 use rustc_span::symbol::{sym, Symbol};
 
 // Any local node that may call something in its body block should be
 // explored. For example, if it's a live Node::Item that is a
 // function, then we should explore its block to check for codes that
 // may need to be marked as live.
-fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
+fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
     matches!(
-        tcx.hir().find(hir_id),
+        tcx.hir().find(tcx.hir().local_def_id_to_hir_id(def_id)),
         Some(
             Node::Item(..)
                 | Node::ImplItem(..)
@@ -31,23 +30,22 @@ fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
                 | Node::TraitItem(..)
                 | Node::Variant(..)
                 | Node::AnonConst(..)
-                | Node::Pat(..),
         )
     )
 }
 
 struct MarkSymbolVisitor<'tcx> {
-    worklist: Vec<hir::HirId>,
+    worklist: Vec<LocalDefId>,
     tcx: TyCtxt<'tcx>,
     maybe_typeck_results: Option<&'tcx ty::TypeckResults<'tcx>>,
-    live_symbols: FxHashSet<hir::HirId>,
+    live_symbols: FxHashSet<LocalDefId>,
     repr_has_repr_c: bool,
     in_pat: bool,
     inherited_pub_visibility: bool,
     pub_visibility: bool,
     ignore_variant_stack: Vec<DefId>,
     // maps from tuple struct constructors to tuple struct items
-    struct_constructors: FxHashMap<hir::HirId, hir::HirId>,
+    struct_constructors: FxHashMap<LocalDefId, LocalDefId>,
 }
 
 impl<'tcx> MarkSymbolVisitor<'tcx> {
@@ -62,19 +60,17 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
 
     fn check_def_id(&mut self, def_id: DefId) {
         if let Some(def_id) = def_id.as_local() {
-            let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
-            if should_explore(self.tcx, hir_id) || self.struct_constructors.contains_key(&hir_id) {
-                self.worklist.push(hir_id);
+            if should_explore(self.tcx, def_id) || self.struct_constructors.contains_key(&def_id) {
+                self.worklist.push(def_id);
             }
-            self.live_symbols.insert(hir_id);
+            self.live_symbols.insert(def_id);
         }
     }
 
     fn insert_def_id(&mut self, def_id: DefId) {
         if let Some(def_id) = def_id.as_local() {
-            let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
-            debug_assert!(!should_explore(self.tcx, hir_id));
-            self.live_symbols.insert(hir_id);
+            debug_assert!(!should_explore(self.tcx, def_id));
+            self.live_symbols.insert(def_id);
         }
     }
 
@@ -233,9 +229,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
 
             // in the case of tuple struct constructors we want to check the item, not the generated
             // tuple struct constructor function
-            let id = self.struct_constructors.get(&id).cloned().unwrap_or(id);
+            let id = self.struct_constructors.get(&id).copied().unwrap_or(id);
 
-            if let Some(node) = self.tcx.hir().find(id) {
+            if let Some(node) = self.tcx.hir().find(self.tcx.hir().local_def_id_to_hir_id(id)) {
                 self.live_symbols.insert(id);
                 self.visit_node(node);
             }
@@ -326,7 +322,8 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
         let live_fields = def.fields().iter().filter(|f| {
             has_repr_c || (pub_visibility && (inherited_pub_visibility || f.vis.node.is_pub()))
         });
-        self.live_symbols.extend(live_fields.map(|f| f.hir_id));
+        let hir = self.tcx.hir();
+        self.live_symbols.extend(live_fields.map(|f| hir.local_def_id(f.hir_id)));
 
         intravisit::walk_struct_def(self, def);
     }
@@ -398,7 +395,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
     }
 
     fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
-        self.live_symbols.insert(c.hir_id);
+        self.live_symbols.insert(self.tcx.hir().local_def_id(c.hir_id));
         intravisit::walk_anon_const(self, c);
     }
 }
@@ -445,47 +442,52 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
 //   2) We are not sure to be live or not
 //     * Implementations of traits and trait methods
 struct LifeSeeder<'k, 'tcx> {
-    worklist: Vec<hir::HirId>,
+    worklist: Vec<LocalDefId>,
     krate: &'k hir::Crate<'k>,
     tcx: TyCtxt<'tcx>,
     // see `MarkSymbolVisitor::struct_constructors`
-    struct_constructors: FxHashMap<hir::HirId, hir::HirId>,
+    struct_constructors: FxHashMap<LocalDefId, LocalDefId>,
 }
 
 impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item<'_>) {
         let allow_dead_code = has_allow_dead_code_or_lang_attr(self.tcx, item.hir_id());
         if allow_dead_code {
-            self.worklist.push(item.hir_id());
+            self.worklist.push(item.def_id);
         }
         match item.kind {
             hir::ItemKind::Enum(ref enum_def, _) => {
+                let hir = self.tcx.hir();
                 if allow_dead_code {
-                    self.worklist.extend(enum_def.variants.iter().map(|variant| variant.id));
+                    self.worklist.extend(
+                        enum_def.variants.iter().map(|variant| hir.local_def_id(variant.id)),
+                    );
                 }
 
                 for variant in enum_def.variants {
                     if let Some(ctor_hir_id) = variant.data.ctor_hir_id() {
-                        self.struct_constructors.insert(ctor_hir_id, variant.id);
+                        self.struct_constructors
+                            .insert(hir.local_def_id(ctor_hir_id), hir.local_def_id(variant.id));
                     }
                 }
             }
             hir::ItemKind::Impl(hir::Impl { ref of_trait, items, .. }) => {
                 if of_trait.is_some() {
-                    self.worklist.push(item.hir_id());
+                    self.worklist.push(item.def_id);
                 }
                 for impl_item_ref in items {
                     let impl_item = self.krate.impl_item(impl_item_ref.id);
                     if of_trait.is_some()
                         || has_allow_dead_code_or_lang_attr(self.tcx, impl_item.hir_id())
                     {
-                        self.worklist.push(impl_item_ref.id.hir_id());
+                        self.worklist.push(impl_item_ref.id.def_id);
                     }
                 }
             }
             hir::ItemKind::Struct(ref variant_data, _) => {
                 if let Some(ctor_hir_id) = variant_data.ctor_hir_id() {
-                    self.struct_constructors.insert(ctor_hir_id, item.hir_id());
+                    self.struct_constructors
+                        .insert(self.tcx.hir().local_def_id(ctor_hir_id), item.def_id);
                 }
             }
             _ => (),
@@ -497,7 +499,7 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
         if matches!(trait_item.kind, Const(_, Some(_)) | Fn(_, hir::TraitFn::Provided(_)))
             && has_allow_dead_code_or_lang_attr(self.tcx, trait_item.hir_id())
         {
-            self.worklist.push(trait_item.hir_id());
+            self.worklist.push(trait_item.def_id);
         }
     }
 
@@ -510,7 +512,7 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
         if matches!(foreign_item.kind, Static(..) | Fn(..))
             && has_allow_dead_code_or_lang_attr(self.tcx, foreign_item.hir_id())
         {
-            self.worklist.push(foreign_item.hir_id());
+            self.worklist.push(foreign_item.def_id);
         }
     }
 }
@@ -519,7 +521,7 @@ fn create_and_seed_worklist<'tcx>(
     tcx: TyCtxt<'tcx>,
     access_levels: &privacy::AccessLevels,
     krate: &hir::Crate<'_>,
-) -> (Vec<hir::HirId>, FxHashMap<hir::HirId, hir::HirId>) {
+) -> (Vec<LocalDefId>, FxHashMap<LocalDefId, LocalDefId>) {
     let worklist = access_levels
         .map
         .iter()
@@ -528,12 +530,8 @@ fn create_and_seed_worklist<'tcx>(
                 if level >= privacy::AccessLevel::Reachable { Some(id) } else { None }
             },
         )
-        .chain(
-            // Seed entry point
-            tcx.entry_fn(()).and_then(|(def_id, _)| {
-                def_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id))
-            }),
-        )
+        // Seed entry point
+        .chain(tcx.entry_fn(()).and_then(|(def_id, _)| def_id.as_local()))
         .collect::<Vec<_>>();
 
     // Seed implemented trait items
@@ -548,7 +546,7 @@ fn find_live<'tcx>(
     tcx: TyCtxt<'tcx>,
     access_levels: &privacy::AccessLevels,
     krate: &hir::Crate<'_>,
-) -> FxHashSet<hir::HirId> {
+) -> FxHashSet<LocalDefId> {
     let (worklist, struct_constructors) = create_and_seed_worklist(tcx, access_levels, krate);
     let mut symbol_visitor = MarkSymbolVisitor {
         worklist,
@@ -568,7 +566,7 @@ fn find_live<'tcx>(
 
 struct DeadVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
-    live_symbols: FxHashSet<hir::HirId>,
+    live_symbols: FxHashSet<LocalDefId>,
 }
 
 impl DeadVisitor<'tcx> {
@@ -583,42 +581,41 @@ impl DeadVisitor<'tcx> {
                 | hir::ItemKind::Struct(..)
                 | hir::ItemKind::Union(..)
         );
-        should_warn && !self.symbol_is_live(item.hir_id())
+        should_warn && !self.symbol_is_live(item.def_id)
     }
 
     fn should_warn_about_field(&mut self, field: &hir::FieldDef<'_>) -> bool {
-        let field_type = self.tcx.type_of(self.tcx.hir().local_def_id(field.hir_id));
+        let def_id = self.tcx.hir().local_def_id(field.hir_id);
+        let field_type = self.tcx.type_of(def_id);
         !field.is_positional()
-            && !self.symbol_is_live(field.hir_id)
+            && !self.symbol_is_live(def_id)
             && !field_type.is_phantom_data()
             && !has_allow_dead_code_or_lang_attr(self.tcx, field.hir_id)
     }
 
     fn should_warn_about_variant(&mut self, variant: &hir::Variant<'_>) -> bool {
-        !self.symbol_is_live(variant.id) && !has_allow_dead_code_or_lang_attr(self.tcx, variant.id)
+        let def_id = self.tcx.hir().local_def_id(variant.id);
+        !self.symbol_is_live(def_id) && !has_allow_dead_code_or_lang_attr(self.tcx, variant.id)
     }
 
     fn should_warn_about_foreign_item(&mut self, fi: &hir::ForeignItem<'_>) -> bool {
-        !self.symbol_is_live(fi.hir_id())
-            && !has_allow_dead_code_or_lang_attr(self.tcx, fi.hir_id())
+        !self.symbol_is_live(fi.def_id) && !has_allow_dead_code_or_lang_attr(self.tcx, fi.hir_id())
     }
 
     // id := HIR id of an item's definition.
-    fn symbol_is_live(&mut self, id: hir::HirId) -> bool {
-        if self.live_symbols.contains(&id) {
+    fn symbol_is_live(&mut self, def_id: LocalDefId) -> bool {
+        if self.live_symbols.contains(&def_id) {
             return true;
         }
         // If it's a type whose items are live, then it's live, too.
         // This is done to handle the case where, for example, the static
         // method of a private type is used, but the type itself is never
         // called directly.
-        let def_id = self.tcx.hir().local_def_id(id);
         let inherent_impls = self.tcx.inherent_impls(def_id);
         for &impl_did in inherent_impls.iter() {
             for item_did in self.tcx.associated_item_def_ids(impl_did) {
-                if let Some(did) = item_did.as_local() {
-                    let item_hir_id = self.tcx.hir().local_def_id_to_hir_id(did);
-                    if self.live_symbols.contains(&item_hir_id) {
+                if let Some(def_id) = item_did.as_local() {
+                    if self.live_symbols.contains(&def_id) {
                         return true;
                     }
                 }
@@ -721,7 +718,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
     fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
         match impl_item.kind {
             hir::ImplItemKind::Const(_, body_id) => {
-                if !self.symbol_is_live(impl_item.hir_id()) {
+                if !self.symbol_is_live(impl_item.def_id) {
                     self.warn_dead_code(
                         impl_item.hir_id(),
                         impl_item.span,
@@ -732,7 +729,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
                 self.visit_nested_body(body_id)
             }
             hir::ImplItemKind::Fn(_, body_id) => {
-                if !self.symbol_is_live(impl_item.hir_id()) {
+                if !self.symbol_is_live(impl_item.def_id) {
                     // FIXME(66095): Because impl_item.span is annotated with things
                     // like expansion data, and ident.span isn't, we use the
                     // def_span method if it's part of a macro invocation
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 0b3227abb5f..ad02f4f8269 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -351,7 +351,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
         if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) =
             item.kind
         {
-            if !self.access_levels.is_reachable(item.hir_id()) {
+            if !self.access_levels.is_reachable(item.def_id) {
                 // FIXME(#53488) remove `let`
                 let tcx = self.tcx;
                 self.worklist.extend(items.iter().map(|ii_ref| ii_ref.id.def_id));
@@ -404,9 +404,7 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> FxHashSet<LocalDefId> {
     //         If other crates link to us, they're going to expect to be able to
     //         use the lang items, so we need to be sure to mark them as
     //         exported.
-    reachable_context
-        .worklist
-        .extend(access_levels.map.iter().map(|(id, _)| tcx.hir().local_def_id(*id)));
+    reachable_context.worklist.extend(access_levels.map.keys());
     for item in tcx.lang_items().items().iter() {
         if let Some(def_id) = *item {
             if let Some(def_id) = def_id.as_local() {
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 3db0409d8f0..484040de0fb 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -7,7 +7,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{FieldDef, Generics, HirId, Item, TraitRef, Ty, TyKind, Variant};
 use rustc_middle::hir::map::Map;
@@ -99,7 +99,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
     // If the node is a function, `fn_sig` is its signature
     fn annotate<F>(
         &mut self,
-        hir_id: HirId,
+        def_id: LocalDefId,
         item_sp: Span,
         fn_sig: Option<&'tcx hir::FnSig<'tcx>>,
         kind: AnnotationKind,
@@ -110,11 +110,11 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
     ) where
         F: FnOnce(&mut Self),
     {
-        let attrs = self.tcx.hir().attrs(hir_id);
-        debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs);
+        let attrs = self.tcx.get_attrs(def_id.to_def_id());
+        debug!("annotate(id = {:?}, attrs = {:?})", def_id, attrs);
         let mut did_error = false;
         if !self.tcx.features().staged_api {
-            did_error = self.forbid_staged_api_attrs(hir_id, attrs, inherit_deprecation.clone());
+            did_error = self.forbid_staged_api_attrs(def_id, attrs, inherit_deprecation.clone());
         }
 
         let depr = if did_error { None } else { attr::find_deprecation(&self.tcx.sess, attrs) };
@@ -123,6 +123,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             is_deprecated = true;
 
             if kind == AnnotationKind::Prohibited || kind == AnnotationKind::DeprecationProhibited {
+                let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
                 self.tcx.struct_span_lint_hir(USELESS_DEPRECATED, hir_id, *span, |lint| {
                     lint.build("this `#[deprecated]` annotation has no effect")
                         .span_suggestion_short(
@@ -136,13 +137,13 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             }
 
             // `Deprecation` is just two pointers, no need to intern it
-            let depr_entry = DeprecationEntry::local(depr.clone(), hir_id);
-            self.index.depr_map.insert(hir_id, depr_entry);
+            let depr_entry = DeprecationEntry::local(depr.clone(), def_id);
+            self.index.depr_map.insert(def_id, depr_entry);
         } else if let Some(parent_depr) = self.parent_depr.clone() {
             if inherit_deprecation.yes() {
                 is_deprecated = true;
-                info!("tagging child {:?} as deprecated from parent", hir_id);
-                self.index.depr_map.insert(hir_id, parent_depr);
+                info!("tagging child {:?} as deprecated from parent", def_id);
+                self.index.depr_map.insert(def_id, parent_depr);
             }
         }
 
@@ -157,7 +158,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             }
         } else {
             self.recurse_with_stability_attrs(
-                depr.map(|(d, _)| DeprecationEntry::local(d, hir_id)),
+                depr.map(|(d, _)| DeprecationEntry::local(d, def_id)),
                 None,
                 None,
                 visit_children,
@@ -170,7 +171,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
 
         let const_stab = const_stab.map(|(const_stab, const_span_node)| {
             let const_stab = self.tcx.intern_const_stability(const_stab);
-            self.index.const_stab_map.insert(hir_id, const_stab);
+            self.index.const_stab_map.insert(def_id, const_stab);
             const_span = Some(const_span_node);
             const_stab
         });
@@ -183,7 +184,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
                 && !fn_sig.header.is_const()
             {
                 if !self.in_trait_impl
-                    || (self.in_trait_impl && !self.tcx.is_const_fn_raw(hir_id.owner.to_def_id()))
+                    || (self.in_trait_impl && !self.tcx.is_const_fn_raw(def_id.to_def_id()))
                 {
                     missing_const_err(&self.tcx.sess, fn_sig.span, const_span);
                 }
@@ -196,7 +197,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
             debug!("annotate: const_stab not found, parent = {:?}", self.parent_const_stab);
             if let Some(parent) = self.parent_const_stab {
                 if parent.level.is_unstable() {
-                    self.index.const_stab_map.insert(hir_id, parent);
+                    self.index.const_stab_map.insert(def_id, parent);
                 }
             }
         }
@@ -271,7 +272,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
                 }
             }
 
-            self.index.stab_map.insert(hir_id, stab);
+            self.index.stab_map.insert(def_id, stab);
             stab
         });
 
@@ -281,13 +282,13 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
                 if inherit_deprecation.yes() && stab.level.is_unstable()
                     || inherit_from_parent.yes()
                 {
-                    self.index.stab_map.insert(hir_id, stab);
+                    self.index.stab_map.insert(def_id, stab);
                 }
             }
         }
 
         self.recurse_with_stability_attrs(
-            depr.map(|(d, _)| DeprecationEntry::local(d, hir_id)),
+            depr.map(|(d, _)| DeprecationEntry::local(d, def_id)),
             stab,
             if inherit_const_stability.yes() { const_stab } else { None },
             visit_children,
@@ -333,7 +334,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
     // returns true if an error occurred, used to suppress some spurious errors
     fn forbid_staged_api_attrs(
         &mut self,
-        hir_id: HirId,
+        def_id: LocalDefId,
         attrs: &[Attribute],
         inherit_deprecation: InheritDeprecation,
     ) -> bool {
@@ -365,7 +366,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         // -Zforce-unstable-if-unmarked is set.
         if let Some(stab) = self.parent_stab {
             if inherit_deprecation.yes() && stab.level.is_unstable() {
-                self.index.stab_map.insert(hir_id, stab);
+                self.index.stab_map.insert(def_id, stab);
             }
         }
 
@@ -407,7 +408,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             hir::ItemKind::Struct(ref sd, _) => {
                 if let Some(ctor_hir_id) = sd.ctor_hir_id() {
                     self.annotate(
-                        ctor_hir_id,
+                        self.tcx.hir().local_def_id(ctor_hir_id),
                         i.span,
                         None,
                         AnnotationKind::Required,
@@ -425,7 +426,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
         }
 
         self.annotate(
-            i.hir_id(),
+            i.def_id,
             i.span,
             fn_sig,
             kind,
@@ -444,7 +445,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
         };
 
         self.annotate(
-            ti.hir_id(),
+            ti.def_id,
             ti.span,
             fn_sig,
             AnnotationKind::Required,
@@ -467,7 +468,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
         };
 
         self.annotate(
-            ii.hir_id(),
+            ii.def_id,
             ii.span,
             fn_sig,
             kind,
@@ -482,7 +483,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
 
     fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) {
         self.annotate(
-            var.id,
+            self.tcx.hir().local_def_id(var.id),
             var.span,
             None,
             AnnotationKind::Required,
@@ -492,7 +493,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             |v| {
                 if let Some(ctor_hir_id) = var.data.ctor_hir_id() {
                     v.annotate(
-                        ctor_hir_id,
+                        v.tcx.hir().local_def_id(ctor_hir_id),
                         var.span,
                         None,
                         AnnotationKind::Required,
@@ -510,7 +511,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
 
     fn visit_field_def(&mut self, s: &'tcx FieldDef<'tcx>) {
         self.annotate(
-            s.hir_id,
+            self.tcx.hir().local_def_id(s.hir_id),
             s.span,
             None,
             AnnotationKind::Required,
@@ -525,7 +526,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
 
     fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem<'tcx>) {
         self.annotate(
-            i.hir_id(),
+            i.def_id,
             i.span,
             None,
             AnnotationKind::Required,
@@ -540,7 +541,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
 
     fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
         self.annotate(
-            md.hir_id(),
+            md.def_id,
             md.span,
             None,
             AnnotationKind::Required,
@@ -560,7 +561,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
         };
 
         self.annotate(
-            p.hir_id,
+            self.tcx.hir().local_def_id(p.hir_id),
             p.span,
             None,
             kind,
@@ -580,22 +581,19 @@ struct MissingStabilityAnnotations<'tcx> {
 }
 
 impl<'tcx> MissingStabilityAnnotations<'tcx> {
-    fn check_missing_stability(&self, hir_id: HirId, span: Span) {
-        let stab = self.tcx.stability().local_stability(hir_id);
-        let is_error =
-            !self.tcx.sess.opts.test && stab.is_none() && self.access_levels.is_reachable(hir_id);
-        if is_error {
-            let def_id = self.tcx.hir().local_def_id(hir_id);
+    fn check_missing_stability(&self, def_id: LocalDefId, span: Span) {
+        let stab = self.tcx.stability().local_stability(def_id);
+        if !self.tcx.sess.opts.test && stab.is_none() && self.access_levels.is_reachable(def_id) {
             let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id());
             self.tcx.sess.span_err(span, &format!("{} has missing stability attribute", descr));
         }
     }
 
-    fn check_missing_const_stability(&self, hir_id: HirId, span: Span) {
+    fn check_missing_const_stability(&self, def_id: LocalDefId, span: Span) {
         let stab_map = self.tcx.stability();
-        let stab = stab_map.local_stability(hir_id);
+        let stab = stab_map.local_stability(def_id);
         if stab.map_or(false, |stab| stab.level.is_stable()) {
-            let const_stab = stab_map.local_const_stability(hir_id);
+            let const_stab = stab_map.local_const_stability(def_id);
             if const_stab.is_none() {
                 self.tcx.sess.span_err(
                     span,
@@ -624,7 +622,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
             hir::ItemKind::Impl(hir::Impl { of_trait: None, .. })
                 | hir::ItemKind::ForeignMod { .. }
         ) {
-            self.check_missing_stability(i.hir_id(), i.span);
+            self.check_missing_stability(i.def_id, i.span);
         }
 
         // Ensure `const fn` that are `stable` have one of `rustc_const_unstable` or
@@ -632,42 +630,42 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
         if self.tcx.features().staged_api
             && matches!(&i.kind, hir::ItemKind::Fn(sig, ..) if sig.header.is_const())
         {
-            self.check_missing_const_stability(i.hir_id(), i.span);
+            self.check_missing_const_stability(i.def_id, i.span);
         }
 
         intravisit::walk_item(self, i)
     }
 
     fn visit_trait_item(&mut self, ti: &'tcx hir::TraitItem<'tcx>) {
-        self.check_missing_stability(ti.hir_id(), ti.span);
+        self.check_missing_stability(ti.def_id, ti.span);
         intravisit::walk_trait_item(self, ti);
     }
 
     fn visit_impl_item(&mut self, ii: &'tcx hir::ImplItem<'tcx>) {
         let impl_def_id = self.tcx.hir().local_def_id(self.tcx.hir().get_parent_item(ii.hir_id()));
         if self.tcx.impl_trait_ref(impl_def_id).is_none() {
-            self.check_missing_stability(ii.hir_id(), ii.span);
+            self.check_missing_stability(ii.def_id, ii.span);
         }
         intravisit::walk_impl_item(self, ii);
     }
 
     fn visit_variant(&mut self, var: &'tcx Variant<'tcx>, g: &'tcx Generics<'tcx>, item_id: HirId) {
-        self.check_missing_stability(var.id, var.span);
+        self.check_missing_stability(self.tcx.hir().local_def_id(var.id), var.span);
         intravisit::walk_variant(self, var, g, item_id);
     }
 
     fn visit_field_def(&mut self, s: &'tcx FieldDef<'tcx>) {
-        self.check_missing_stability(s.hir_id, s.span);
+        self.check_missing_stability(self.tcx.hir().local_def_id(s.hir_id), s.span);
         intravisit::walk_field_def(self, s);
     }
 
     fn visit_foreign_item(&mut self, i: &'tcx hir::ForeignItem<'tcx>) {
-        self.check_missing_stability(i.hir_id(), i.span);
+        self.check_missing_stability(i.def_id, i.span);
         intravisit::walk_foreign_item(self, i);
     }
 
     fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef<'tcx>) {
-        self.check_missing_stability(md.hir_id(), md.span);
+        self.check_missing_stability(md.def_id, md.span);
     }
 
     // Note that we don't need to `check_missing_stability` for default generic parameters,
@@ -731,7 +729,7 @@ fn stability_index(tcx: TyCtxt<'tcx>, (): ()) -> Index<'tcx> {
         }
 
         annotator.annotate(
-            hir::CRATE_HIR_ID,
+            CRATE_DEF_ID,
             krate.module().inner,
             None,
             AnnotationKind::Required,
@@ -929,7 +927,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
     if tcx.stability().staged_api[&LOCAL_CRATE] {
         let krate = tcx.hir().krate();
         let mut missing = MissingStabilityAnnotations { tcx, access_levels };
-        missing.check_missing_stability(hir::CRATE_HIR_ID, krate.module().inner);
+        missing.check_missing_stability(CRATE_DEF_ID, krate.module().inner);
         intravisit::walk_crate(&mut missing, krate);
         krate.visit_all_item_likes(&mut missing.as_deep_visitor());
     }