From e8aeb83a4a1f242c4ff1394b645cc180fcdd5b23 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Sun, 3 Feb 2019 09:14:31 +0100 Subject: [PATCH] hir: add HirId methods --- src/librustc/hir/map/collector.rs | 6 ++ src/librustc/hir/map/definitions.rs | 40 ++++++++++++- src/librustc/hir/map/mod.rs | 87 +++++++++++++++++++++++++++++ src/librustc/ty/item_path.rs | 6 ++ 4 files changed, 138 insertions(+), 1 deletion(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 7cc5d756ff31..9c4fa9e12728 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -1,5 +1,6 @@ use super::*; use dep_graph::{DepGraph, DepKind, DepNodeIndex}; +use hir; use hir::def_id::{LOCAL_CRATE, CrateNum}; use hir::intravisit::{Visitor, NestedVisitorMap}; use rustc_data_structures::svh::Svh; @@ -28,6 +29,8 @@ pub(super) struct NodeCollector<'a, 'hir> { /// The parent of this node parent_node: NodeId, + parent_hir: hir::HirId, + // These fields keep track of the currently relevant DepNodes during // the visitor's traversal. current_dep_node_owner: DefIndex, @@ -145,6 +148,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { source_map: sess.source_map(), map: repeat(None).take(sess.current_node_id_count()).collect(), parent_node: CRATE_NODE_ID, + parent_hir: hir::CRATE_HIR_ID, current_signature_dep_index: root_mod_sig_dep_index, current_full_dep_index: root_mod_full_dep_index, current_dep_node_owner: CRATE_DEF_INDEX, @@ -156,6 +160,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { }; collector.insert_entry(CRATE_NODE_ID, Entry { parent: CRATE_NODE_ID, + parent_hir: hir::CRATE_HIR_ID, dep_node: root_mod_sig_dep_index, node: Node::Crate, }); @@ -226,6 +231,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { fn insert(&mut self, span: Span, id: NodeId, node: Node<'hir>) { let entry = Entry { parent: self.parent_node, + parent_hir: self.parent_hir, dep_node: if self.currently_in_body { self.current_full_dep_index } else { diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 1b7445199475..687daca3d3ff 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -20,7 +20,7 @@ use syntax::ast; use syntax::ext::hygiene::Mark; use syntax::symbol::{Symbol, InternedString}; use syntax_pos::{Span, DUMMY_SP}; -use util::nodemap::NodeMap; +use util::nodemap::{HirIdMap, NodeMap}; /// The DefPathTable maps DefIndexes to DefKeys and vice versa. /// Internally the DefPathTable holds a tree of DefKeys, where each DefKey @@ -147,6 +147,7 @@ impl Decodable for DefPathTable { pub struct Definitions { table: DefPathTable, node_to_def_index: NodeMap, + hir_to_def_index: HirIdMap, def_index_to_node: [Vec; 2], pub(super) node_to_hir_id: IndexVec, /// If `Mark` is an ID of some macro expansion, @@ -441,16 +442,34 @@ impl Definitions { self.node_to_def_index.get(&node).cloned() } + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn opt_def_index_from_hir_id(&self, hir: hir::HirId) -> Option { + self.hir_to_def_index.get(&hir).cloned() + } + #[inline] pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option { self.opt_def_index(node).map(DefId::local) } + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn opt_local_def_id_from_hir_id(&self, hir: hir::HirId) -> Option { + self.opt_def_index_from_hir_id(hir).map(DefId::local) + } + #[inline] pub fn local_def_id(&self, node: ast::NodeId) -> DefId { self.opt_local_def_id(node).unwrap() } + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn local_def_id_from_hir_id(&self, hir: hir::HirId) -> DefId { + self.opt_local_def_id_from_hir_id(hir).unwrap() + } + #[inline] pub fn as_local_node_id(&self, def_id: DefId) -> Option { if def_id.krate == LOCAL_CRATE { @@ -467,6 +486,21 @@ impl Definitions { } } + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn as_local_hir_id(&self, def_id: DefId) -> Option { + if def_id.krate == LOCAL_CRATE { + let hir_id = self.def_index_to_hir_id(def_id.index); + if hir_id != hir::DUMMY_HIR_ID { + Some(hir_id) + } else { + None + } + } else { + None + } + } + #[inline] pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId { self.node_to_hir_id[node_id] @@ -515,6 +549,7 @@ impl Definitions { assert!(self.def_index_to_node[address_space.index()].is_empty()); self.def_index_to_node[address_space.index()].push(ast::CRATE_NODE_ID); self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index); + self.hir_to_def_index.insert(hir::CRATE_HIR_ID, root_index); // Allocate some other DefIndices that always must exist. GlobalMetaDataKind::allocate_def_indices(self); @@ -575,6 +610,9 @@ impl Definitions { 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); + if let Some(hir_id) = self.node_to_hir_id.get(node_id) { + self.hir_to_def_index.insert(*hir_id, index); + } } if expansion != Mark::root() { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 9066f2238cf2..c8e19c3b4926 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -40,6 +40,7 @@ pub const REGULAR_SPACE: DefIndexAddressSpace = DefIndexAddressSpace::High; #[derive(Copy, Clone, Debug)] pub struct Entry<'hir> { parent: NodeId, + parent_hir: HirId, dep_node: DepNodeIndex, node: Node<'hir>, } @@ -208,6 +209,12 @@ impl<'hir> Map<'hir> { } } + // FIXME(@ljedrz): replace the NodeId variant + pub fn read_by_hir_id(&self, hir_id: HirId) { + let node_id = self.hir_to_node_id(hir_id); + self.read(node_id); + } + #[inline] pub fn definitions(&self) -> &'hir Definitions { self.definitions @@ -224,6 +231,11 @@ impl<'hir> Map<'hir> { }) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn def_path_from_hir_id(&self, id: HirId) -> DefPath { + self.def_path(self.local_def_id_from_hir_id(id)) + } + pub fn def_path(&self, def_id: DefId) -> DefPath { assert!(def_id.is_local()); self.definitions.def_path(def_id.index) @@ -237,6 +249,22 @@ impl<'hir> Map<'hir> { }) } + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn local_def_id_from_hir_id(&self, hir_id: HirId) -> DefId { + self.opt_local_def_id_from_hir_id(hir_id).unwrap_or_else(|| { + let node_id = self.hir_to_node_id(hir_id); + bug!("local_def_id_from_hir_id: no entry for `{:?}`, which has a map of `{:?}`", + hir_id, self.find_entry(node_id)) + }) + } + + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn opt_local_def_id_from_hir_id(&self, hir_id: HirId) -> Option { + self.definitions.opt_local_def_id_from_hir_id(hir_id) + } + #[inline] pub fn opt_local_def_id(&self, node: NodeId) -> Option { self.definitions.opt_local_def_id(node) @@ -247,6 +275,12 @@ impl<'hir> Map<'hir> { self.definitions.as_local_node_id(def_id) } + // FIXME(@ljedrz): replace the NodeId variant + #[inline] + pub fn as_local_hir_id(&self, def_id: DefId) -> Option { + self.definitions.as_local_hir_id(def_id) + } + #[inline] pub fn hir_to_node_id(&self, hir_id: HirId) -> NodeId { self.hir_to_node_id[&hir_id] @@ -566,6 +600,12 @@ impl<'hir> Map<'hir> { self.find(id).unwrap_or_else(|| bug!("couldn't find node id {} in the AST map", id)) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn get_by_hir_id(&self, id: HirId) -> Node<'hir> { + let node_id = self.hir_to_node_id(id); + self.get(node_id) + } + pub fn get_if_local(&self, id: DefId) -> Option> { self.as_local_node_id(id).map(|id| self.get(id)) // read recorded by `get` } @@ -613,6 +653,12 @@ impl<'hir> Map<'hir> { result } + // FIXME(@ljedrz): replace the NodeId variant + pub fn find_by_hir_id(&self, hir_id: HirId) -> Option> { + let node_id = self.hir_to_node_id(hir_id); + self.find(node_id) + } + /// Similar to `get_parent`; returns the parent node-id, or own `id` if there is /// no parent. Note that the parent may be `CRATE_NODE_ID`, which is not itself /// present in the map -- so passing the return value of get_parent_node to @@ -633,6 +679,13 @@ impl<'hir> Map<'hir> { self.find_entry(id).and_then(|x| x.parent_node()).unwrap_or(id) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn get_parent_node_by_hir_id(&self, id: HirId) -> HirId { + let node_id = self.hir_to_node_id(id); + let parent_node_id = self.get_parent_node(node_id); + self.node_to_hir_id(parent_node_id) + } + /// Check if the node is an argument. An argument is a local variable whose /// immediate parent is an item or a closure. pub fn is_argument(&self, id: NodeId) -> bool { @@ -757,6 +810,13 @@ impl<'hir> Map<'hir> { } } + // FIXME(@ljedrz): replace the NodeId variant + pub fn get_parent_item(&self, id: HirId) -> HirId { + let node_id = self.hir_to_node_id(id); + let parent_node_id = self.get_parent(node_id); + self.node_to_hir_id(parent_node_id) + } + /// Returns the `DefId` of `id`'s nearest module parent, or `id` itself if no /// module parent is in this map. pub fn get_module_parent(&self, id: NodeId) -> DefId { @@ -814,6 +874,12 @@ impl<'hir> Map<'hir> { } } + // FIXME(@ljedrz): replace the NodeId variant + pub fn expect_item_by_hir_id(&self, id: HirId) -> &'hir Item { + let node_id = self.hir_to_node_id(id); + self.expect_item(node_id) + } + pub fn expect_impl_item(&self, id: NodeId) -> &'hir ImplItem { match self.find(id) { Some(Node::ImplItem(item)) => item, @@ -960,13 +1026,28 @@ impl<'hir> Map<'hir> { node_id_to_string(self, id, true) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn hir_to_string(&self, id: HirId) -> String { + hir_id_to_string(self, id, true) + } + pub fn node_to_user_string(&self, id: NodeId) -> String { node_id_to_string(self, id, false) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn hir_to_user_string(&self, id: HirId) -> String { + hir_id_to_string(self, id, false) + } + pub fn node_to_pretty_string(&self, id: NodeId) -> String { print::to_string(self, |s| s.print_node(self.get(id))) } + + // FIXME(@ljedrz): replace the NodeId variant + pub fn hir_to_pretty_string(&self, id: HirId) -> String { + print::to_string(self, |s| s.print_node(self.get_by_hir_id(id))) + } } pub struct NodesMatchingSuffix<'a, 'hir:'a> { @@ -1310,6 +1391,12 @@ fn node_id_to_string(map: &Map<'_>, id: NodeId, include_id: bool) -> String { } } +// FIXME(@ljedrz): replace the NodeId variant +fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String { + let node_id = map.hir_to_node_id(id); + node_id_to_string(map, node_id, include_id) +} + pub fn describe_def(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> Option { if let Some(node_id) = tcx.hir().as_local_node_id(def_id) { tcx.hir().describe_def(node_id) diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 0ddc5ae87208..adb7e1fb3e32 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -1,3 +1,4 @@ +use hir; use hir::map::DefPathData; use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use ty::{self, DefIdTree, Ty, TyCtxt}; @@ -76,6 +77,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.item_path_str(self.hir().local_def_id(id)) } + // FIXME(@ljedrz): replace the NodeId variant + pub fn hir_path_str(self, id: hir::HirId) -> String { + self.item_path_str(self.hir().local_def_id_from_hir_id(id)) + } + /// Returns a string identifying this def-id. This string is /// suitable for user output. It always begins with a crate identifier. pub fn absolute_item_path_str(self, def_id: DefId) -> String {