]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/hir/map/definitions.rs
Rollup merge of #70038 - DutchGhost:const-forget-tests, r=RalfJung
[rust.git] / src / librustc / hir / map / definitions.rs
index e1b5ec041db060624fced447af1dd25ef26bdcff..aa4742ea891bb7e19580f139ddc67d327e74d0e4 100644 (file)
@@ -5,22 +5,21 @@
 //! expressions) that are mostly just leftovers.
 
 use rustc_ast::ast;
-use rustc_ast::node_id::NodeMap;
-use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_hir as hir;
-use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_index::vec::IndexVec;
 use rustc_session::CrateDisambiguator;
 use rustc_span::hygiene::ExpnId;
 use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 
-use std::borrow::Borrow;
 use std::fmt::Write;
 use std::hash::Hash;
 
+pub use rustc_hir::def_id::DefPathHash;
+
 /// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa.
 /// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
 /// stores the `DefIndex` of its parent.
@@ -78,21 +77,29 @@ pub fn size(&self) -> usize {
 #[derive(Clone, Default)]
 pub struct Definitions {
     table: DefPathTable,
-    node_to_def_index: NodeMap<DefIndex>,
-    def_index_to_node: IndexVec<DefIndex, ast::NodeId>,
-    pub(super) node_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
+
+    def_id_to_span: IndexVec<LocalDefId, Span>,
+
+    // FIXME(eddyb) don't go through `ast::NodeId` to convert between `HirId`
+    // and `LocalDefId` - ideally all `LocalDefId`s would be HIR owners.
+    node_id_to_def_id: FxHashMap<ast::NodeId, LocalDefId>,
+    def_id_to_node_id: IndexVec<LocalDefId, ast::NodeId>,
+
+    pub(super) node_id_to_hir_id: IndexVec<ast::NodeId, hir::HirId>,
+    /// The reverse mapping of `node_id_to_hir_id`.
+    pub(super) hir_id_to_node_id: FxHashMap<hir::HirId, ast::NodeId>,
+
     /// If `ExpnId` is an ID of some macro expansion,
     /// then `DefId` is the normal module (`mod`) in which the expanded macro was defined.
     parent_modules_of_macro_defs: FxHashMap<ExpnId, DefId>,
-    /// Item with a given `DefIndex` was defined during macro expansion with ID `ExpnId`.
-    expansions_that_defined: FxHashMap<DefIndex, ExpnId>,
-    next_disambiguator: FxHashMap<(DefIndex, DefPathData), u32>,
-    def_index_to_span: FxHashMap<DefIndex, Span>,
+    /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
+    expansions_that_defined: FxHashMap<LocalDefId, ExpnId>,
+    next_disambiguator: FxHashMap<(LocalDefId, DefPathData), u32>,
     /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
     /// we know what parent node that fragment should be attached to thanks to this table.
-    invocation_parents: FxHashMap<ExpnId, DefIndex>,
+    invocation_parents: FxHashMap<ExpnId, LocalDefId>,
     /// Indices of unnamed struct or variant fields with unresolved attributes.
-    placeholder_field_indices: NodeMap<usize>,
+    placeholder_field_indices: FxHashMap<ast::NodeId, usize>,
 }
 
 /// A unique identifier that we can use to lookup a definition
@@ -282,28 +289,6 @@ pub enum DefPathData {
     ImplTrait,
 }
 
-#[derive(
-    Copy,
-    Clone,
-    Hash,
-    PartialEq,
-    Eq,
-    PartialOrd,
-    Ord,
-    Debug,
-    RustcEncodable,
-    RustcDecodable,
-    HashStable
-)]
-pub struct DefPathHash(pub Fingerprint);
-
-impl Borrow<Fingerprint> for DefPathHash {
-    #[inline]
-    fn borrow(&self) -> &Fingerprint {
-        &self.0
-    }
-}
-
 impl Definitions {
     pub fn def_path_table(&self) -> &DefPathTable {
         &self.table
@@ -314,13 +299,13 @@ pub fn def_index_count(&self) -> usize {
         self.table.index_to_key.len()
     }
 
-    pub fn def_key(&self, index: DefIndex) -> DefKey {
-        self.table.def_key(index)
+    pub fn def_key(&self, id: LocalDefId) -> DefKey {
+        self.table.def_key(id.local_def_index)
     }
 
     #[inline(always)]
-    pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
-        self.table.def_path_hash(index)
+    pub fn def_path_hash(&self, id: LocalDefId) -> DefPathHash {
+        self.table.def_path_hash(id.local_def_index)
     }
 
     /// Returns the path from the crate root to `index`. The root
@@ -328,29 +313,27 @@ pub fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
     /// empty vector for the crate root). For an inlined item, this
     /// will be the path of the item in the external crate (but the
     /// path will begin with the path to the external crate).
-    pub fn def_path(&self, index: DefIndex) -> DefPath {
-        DefPath::make(LOCAL_CRATE, index, |p| self.def_key(p))
-    }
-
-    #[inline]
-    pub fn opt_def_index(&self, node: ast::NodeId) -> Option<DefIndex> {
-        self.node_to_def_index.get(&node).copied()
+    pub fn def_path(&self, id: LocalDefId) -> DefPath {
+        DefPath::make(LOCAL_CRATE, id.local_def_index, |index| {
+            self.def_key(LocalDefId { local_def_index: index })
+        })
     }
 
     #[inline]
-    pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option<DefId> {
-        self.opt_def_index(node).map(DefId::local)
+    pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option<LocalDefId> {
+        self.node_id_to_def_id.get(&node).copied()
     }
 
+    // FIXME(eddyb) this function can and should return `LocalDefId`.
     #[inline]
     pub fn local_def_id(&self, node: ast::NodeId) -> DefId {
-        self.opt_local_def_id(node).unwrap()
+        self.opt_local_def_id(node).unwrap().to_def_id()
     }
 
     #[inline]
     pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
-        if def_id.krate == LOCAL_CRATE {
-            let node_id = self.def_index_to_node[def_id.index];
+        if let Some(def_id) = def_id.as_local() {
+            let node_id = self.def_id_to_node_id[def_id];
             if node_id != ast::DUMMY_NODE_ID {
                 return Some(node_id);
             }
@@ -360,34 +343,36 @@ pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
 
     #[inline]
     pub fn as_local_hir_id(&self, def_id: DefId) -> Option<hir::HirId> {
-        if def_id.krate == LOCAL_CRATE {
-            let hir_id = self.def_index_to_hir_id(def_id.index);
+        if let Some(def_id) = def_id.as_local() {
+            let hir_id = self.local_def_id_to_hir_id(def_id);
             if hir_id != hir::DUMMY_HIR_ID { Some(hir_id) } else { None }
         } else {
             None
         }
     }
 
+    // FIXME(eddyb) rename to `hir_id_to_node_id`.
+    #[inline]
+    pub fn hir_to_node_id(&self, hir_id: hir::HirId) -> ast::NodeId {
+        self.hir_id_to_node_id[&hir_id]
+    }
+
+    // FIXME(eddyb) rename to `node_id_to_hir_id`.
     #[inline]
     pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId {
-        self.node_to_hir_id[node_id]
+        self.node_id_to_hir_id[node_id]
     }
 
     #[inline]
-    pub fn def_index_to_hir_id(&self, def_index: DefIndex) -> hir::HirId {
-        let node_id = self.def_index_to_node[def_index];
-        self.node_to_hir_id[node_id]
+    pub fn local_def_id_to_hir_id(&self, id: LocalDefId) -> hir::HirId {
+        let node_id = self.def_id_to_node_id[id];
+        self.node_id_to_hir_id[node_id]
     }
 
-    /// Retrieves the span of the given `DefId` if `DefId` is in the local crate, the span exists
-    /// and it's not `DUMMY_SP`.
+    /// Retrieves the span of the given `DefId` if `DefId` is in the local crate.
     #[inline]
     pub fn opt_span(&self, def_id: DefId) -> Option<Span> {
-        if def_id.krate == LOCAL_CRATE {
-            self.def_index_to_span.get(&def_id.index).copied()
-        } else {
-            None
-        }
+        if let Some(def_id) = def_id.as_local() { Some(self.def_id_to_span[def_id]) } else { None }
     }
 
     /// Adds a root definition (no parent) and a few other reserved definitions.
@@ -395,7 +380,7 @@ pub fn create_root_def(
         &mut self,
         crate_name: &str,
         crate_disambiguator: CrateDisambiguator,
-    ) -> DefIndex {
+    ) -> LocalDefId {
         let key = DefKey {
             parent: None,
             disambiguated_data: DisambiguatedDefPathData {
@@ -408,36 +393,38 @@ pub fn create_root_def(
         let def_path_hash = key.compute_stable_hash(parent_hash);
 
         // Create the definition.
-        let root_index = self.table.allocate(key, def_path_hash);
-        assert_eq!(root_index, CRATE_DEF_INDEX);
-        assert!(self.def_index_to_node.is_empty());
-        self.def_index_to_node.push(ast::CRATE_NODE_ID);
-        self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index);
-        self.set_invocation_parent(ExpnId::root(), root_index);
+        let root = LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) };
+        assert_eq!(root.local_def_index, CRATE_DEF_INDEX);
+
+        assert_eq!(self.def_id_to_node_id.push(ast::CRATE_NODE_ID), root);
+        assert_eq!(self.def_id_to_span.push(rustc_span::DUMMY_SP), root);
 
-        root_index
+        self.node_id_to_def_id.insert(ast::CRATE_NODE_ID, root);
+        self.set_invocation_parent(ExpnId::root(), root);
+
+        root
     }
 
     /// Adds a definition with a parent definition.
     pub fn create_def_with_parent(
         &mut self,
-        parent: DefIndex,
+        parent: LocalDefId,
         node_id: ast::NodeId,
         data: DefPathData,
         expn_id: ExpnId,
         span: Span,
-    ) -> DefIndex {
+    ) -> LocalDefId {
         debug!(
             "create_def_with_parent(parent={:?}, node_id={:?}, data={:?})",
             parent, node_id, data
         );
 
         assert!(
-            !self.node_to_def_index.contains_key(&node_id),
+            !self.node_id_to_def_id.contains_key(&node_id),
             "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
             node_id,
             data,
-            self.table.def_key(self.node_to_def_index[&node_id])
+            self.table.def_key(self.node_id_to_def_id[&node_id].local_def_index),
         );
 
         // The root node must be created with `create_root_def()`.
@@ -452,52 +439,55 @@ pub fn create_def_with_parent(
         };
 
         let key = DefKey {
-            parent: Some(parent),
+            parent: Some(parent.local_def_index),
             disambiguated_data: DisambiguatedDefPathData { data, disambiguator },
         };
 
-        let parent_hash = self.table.def_path_hash(parent);
+        let parent_hash = self.table.def_path_hash(parent.local_def_index);
         let def_path_hash = key.compute_stable_hash(parent_hash);
 
         debug!("create_def_with_parent: after disambiguation, key = {:?}", key);
 
         // Create the definition.
-        let index = self.table.allocate(key, def_path_hash);
-        assert_eq!(index.index(), self.def_index_to_node.len());
-        self.def_index_to_node.push(node_id);
+        let def_id = LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) };
+
+        assert_eq!(self.def_id_to_node_id.push(node_id), def_id);
+        assert_eq!(self.def_id_to_span.push(span), def_id);
 
-        // Some things for which we allocate `DefIndex`es don't correspond to
+        // Some things for which we allocate `LocalDefId`s don't correspond to
         // anything in the AST, so they don't have a `NodeId`. For these cases
-        // we don't need a mapping from `NodeId` to `DefIndex`.
+        // we don't need a mapping from `NodeId` to `LocalDefId`.
         if node_id != ast::DUMMY_NODE_ID {
-            debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
-            self.node_to_def_index.insert(node_id, index);
+            debug!("create_def_with_parent: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
+            self.node_id_to_def_id.insert(node_id, def_id);
         }
 
         if expn_id != ExpnId::root() {
-            self.expansions_that_defined.insert(index, expn_id);
-        }
-
-        // The span is added if it isn't dummy.
-        if !span.is_dummy() {
-            self.def_index_to_span.insert(index, span);
+            self.expansions_that_defined.insert(def_id, expn_id);
         }
 
-        index
+        def_id
     }
 
     /// Initializes the `ast::NodeId` to `HirId` mapping once it has been generated during
     /// AST to HIR lowering.
     pub fn init_node_id_to_hir_id_mapping(&mut self, mapping: IndexVec<ast::NodeId, hir::HirId>) {
         assert!(
-            self.node_to_hir_id.is_empty(),
+            self.node_id_to_hir_id.is_empty(),
             "trying to initialize `NodeId` -> `HirId` mapping twice"
         );
-        self.node_to_hir_id = mapping;
+        self.node_id_to_hir_id = mapping;
+
+        // Build the reverse mapping of `node_id_to_hir_id`.
+        self.hir_id_to_node_id = self
+            .node_id_to_hir_id
+            .iter_enumerated()
+            .map(|(node_id, &hir_id)| (hir_id, node_id))
+            .collect();
     }
 
-    pub fn expansion_that_defined(&self, index: DefIndex) -> ExpnId {
-        self.expansions_that_defined.get(&index).copied().unwrap_or(ExpnId::root())
+    pub fn expansion_that_defined(&self, id: LocalDefId) -> ExpnId {
+        self.expansions_that_defined.get(&id).copied().unwrap_or(ExpnId::root())
     }
 
     pub fn parent_module_of_macro_def(&self, expn_id: ExpnId) -> DefId {
@@ -508,13 +498,13 @@ pub fn add_parent_module_of_macro_def(&mut self, expn_id: ExpnId, module: DefId)
         self.parent_modules_of_macro_defs.insert(expn_id, module);
     }
 
-    pub fn invocation_parent(&self, invoc_id: ExpnId) -> DefIndex {
+    pub fn invocation_parent(&self, invoc_id: ExpnId) -> LocalDefId {
         self.invocation_parents[&invoc_id]
     }
 
-    pub fn set_invocation_parent(&mut self, invoc_id: ExpnId, parent: DefIndex) {
+    pub fn set_invocation_parent(&mut self, invoc_id: ExpnId, parent: LocalDefId) {
         let old_parent = self.invocation_parents.insert(invoc_id, parent);
-        assert!(old_parent.is_none(), "parent `DefIndex` is reset for an invocation");
+        assert!(old_parent.is_none(), "parent `LocalDefId` is reset for an invocation");
     }
 
     pub fn placeholder_field_index(&self, node_id: ast::NodeId) -> usize {