From f60513ec8d97414a346cedb755a4cac3abd55ed1 Mon Sep 17 00:00:00 2001 From: marmeladema Date: Sat, 20 Jun 2020 19:59:29 +0100 Subject: [PATCH 1/3] Move remaining `NodeId` APIs from `Definitions` to `Resolver` --- Cargo.lock | 1 + src/librustc_ast_lowering/item.rs | 17 +-- src/librustc_ast_lowering/lib.rs | 50 ++++++--- src/librustc_hir/definitions.rs | 105 ++---------------- src/librustc_metadata/creader.rs | 4 +- src/librustc_resolve/Cargo.toml | 1 + src/librustc_resolve/build_reduced_graph.rs | 67 +++++------ src/librustc_resolve/check_unused.rs | 5 +- src/librustc_resolve/def_collector.rs | 27 +++-- src/librustc_resolve/diagnostics.rs | 8 +- src/librustc_resolve/imports.rs | 3 +- src/librustc_resolve/late.rs | 17 +-- src/librustc_resolve/late/diagnostics.rs | 6 +- src/librustc_resolve/lib.rs | 117 ++++++++++++++++---- src/librustc_resolve/macros.rs | 7 +- 15 files changed, 219 insertions(+), 216 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5bb6cda64cba8..d5bc99e12651f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4242,6 +4242,7 @@ dependencies = [ "rustc_expand", "rustc_feature", "rustc_hir", + "rustc_index", "rustc_metadata", "rustc_middle", "rustc_session", diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 8cfbd408e22b3..00665c4cafb6b 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -253,7 +253,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ItemKind::Const(ty, body_id) } ItemKind::Fn(_, FnSig { ref decl, header }, ref generics, ref body) => { - let fn_def_id = self.resolver.definitions().local_def_id(id); + let fn_def_id = self.resolver.local_def_id(id); self.with_new_scopes(|this| { this.current_item = Some(ident.span); @@ -342,7 +342,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self_ty: ref ty, items: ref impl_items, } => { - let def_id = self.resolver.definitions().local_def_id(id); + let def_id = self.resolver.local_def_id(id); // Lower the "impl header" first. This ordering is important // for in-band lifetimes! Consider `'a` here: @@ -646,7 +646,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem<'hir> { - let def_id = self.resolver.definitions().local_def_id(i.id); + let def_id = self.resolver.local_def_id(i.id); hir::ForeignItem { hir_id: self.lower_node_id(i.id), ident: i.ident, @@ -747,7 +747,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_trait_item(&mut self, i: &AssocItem) -> hir::TraitItem<'hir> { - let trait_item_def_id = self.resolver.definitions().local_def_id(i.id); + let trait_item_def_id = self.resolver.local_def_id(i.id); let (generics, kind) = match i.kind { AssocItemKind::Const(_, ref ty, ref default) => { @@ -812,7 +812,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_impl_item(&mut self, i: &AssocItem) -> hir::ImplItem<'hir> { - let impl_item_def_id = self.resolver.definitions().local_def_id(i.id); + let impl_item_def_id = self.resolver.local_def_id(i.id); let (generics, kind) = match &i.kind { AssocItemKind::Const(_, ty, expr) => { @@ -1320,12 +1320,7 @@ impl<'hir> LoweringContext<'_, 'hir> { if let Some(def_id) = def_id.as_local() { for param in &generics.params { if let GenericParamKind::Type { .. } = param.kind { - if def_id - == self - .resolver - .definitions() - .local_def_id(param.id) - { + if def_id == self.resolver.local_def_id(param.id) { add_bounds .entry(param.id) .or_default() diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 335cc3e61040d..ac8a229da43db 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -54,7 +54,7 @@ use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX}; use rustc_hir::definitions::{DefKey, DefPathData, Definitions}; use rustc_hir::intravisit; use rustc_hir::{ConstArg, GenericArg, ParamName}; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{Idx, IndexVec}; use rustc_session::config::nightly_options; use rustc_session::lint::{builtin::BARE_TRAIT_OBJECTS, BuiltinLintDiagnostics, LintBuffer}; use rustc_session::parse::ParseSess; @@ -205,6 +205,19 @@ pub trait Resolver { fn next_node_id(&mut self) -> NodeId; fn trait_map(&self) -> &NodeMap>; + + fn opt_local_def_id(&self, node: NodeId) -> Option; + + fn local_def_id(&self, node: NodeId) -> LocalDefId; + + fn create_def_with_parent( + &mut self, + parent: LocalDefId, + node_id: ast::NodeId, + data: DefPathData, + expn_id: ExpnId, + span: Span, + ) -> LocalDefId; } type NtToTokenstream = fn(&Nonterminal, &ParseSess, Span) -> TokenStream; @@ -436,7 +449,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { match tree.kind { UseTreeKind::Simple(_, id1, id2) => { for &id in &[id1, id2] { - self.lctx.resolver.definitions().create_def_with_parent( + self.lctx.resolver.create_def_with_parent( owner, id, DefPathData::Misc, @@ -488,7 +501,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | ItemKind::Enum(_, ref generics) | ItemKind::TyAlias(_, ref generics, ..) | ItemKind::Trait(_, _, ref generics, ..) => { - let def_id = self.lctx.resolver.definitions().local_def_id(item.id); + let def_id = self.lctx.resolver.local_def_id(item.id); let count = generics .params .iter() @@ -564,7 +577,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .map(|(&k, v)| (self.node_id_to_hir_id[k].unwrap(), v.clone())) .collect(); - self.resolver.definitions().init_node_id_to_hir_id_mapping(self.node_id_to_hir_id); + let mut def_id_to_hir_id = IndexVec::default(); + + for (node_id, hir_id) in self.node_id_to_hir_id.into_iter_enumerated() { + if let Some(def_id) = self.resolver.opt_local_def_id(node_id) { + if def_id_to_hir_id.len() <= def_id.index() { + def_id_to_hir_id.resize(def_id.index() + 1, None); + } + def_id_to_hir_id[def_id] = hir_id; + } + } + + self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id); hir::Crate { item: hir::CrateItem { module, attrs, span: c.span }, @@ -628,7 +652,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .item_local_id_counters .insert(owner, HIR_ID_COUNTER_LOCKED) .unwrap_or_else(|| panic!("no `item_local_id_counters` entry for {:?}", owner)); - let def_id = self.resolver.definitions().local_def_id(owner); + let def_id = self.resolver.local_def_id(owner); self.current_hir_id_owner.push((def_id, counter)); let ret = f(self); let (new_def_id, new_counter) = self.current_hir_id_owner.pop().unwrap(); @@ -671,7 +695,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { debug_assert!(local_id != HIR_ID_COUNTER_LOCKED); *local_id_counter += 1; - let owner = this.resolver.definitions().opt_local_def_id(owner).expect( + let owner = this.resolver.opt_local_def_id(owner).expect( "you forgot to call `create_def_with_parent` or are lowering node-IDs \ that do not belong to the current owner", ); @@ -800,7 +824,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; // Add a definition for the in-band lifetime def. - self.resolver.definitions().create_def_with_parent( + self.resolver.create_def_with_parent( parent_def_id, node_id, DefPathData::LifetimeNs(str_name), @@ -1088,7 +1112,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let impl_trait_node_id = self.resolver.next_node_id(); let parent_def_id = self.current_hir_id_owner.last().unwrap().0; - self.resolver.definitions().create_def_with_parent( + self.resolver.create_def_with_parent( parent_def_id, impl_trait_node_id, DefPathData::ImplTrait, @@ -1154,7 +1178,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let node_id = self.resolver.next_node_id(); // Add a definition for the in-band const def. - self.resolver.definitions().create_def_with_parent( + self.resolver.create_def_with_parent( parent_def_id, node_id, DefPathData::AnonConst, @@ -1339,7 +1363,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } ImplTraitContext::Universal(in_band_ty_params) => { // Add a definition for the in-band `Param`. - let def_id = self.resolver.definitions().local_def_id(def_node_id); + let def_id = self.resolver.local_def_id(def_node_id); let hir_bounds = self.lower_param_bounds( bounds, @@ -1428,7 +1452,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // frequently opened issues show. let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); - let opaque_ty_def_id = self.resolver.definitions().local_def_id(opaque_ty_node_id); + let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id); self.allocate_hir_id_counter(opaque_ty_node_id); @@ -1620,7 +1644,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let def_node_id = self.context.resolver.next_node_id(); let hir_id = self.context.lower_node_id_with_owner(def_node_id, self.opaque_ty_id); - self.context.resolver.definitions().create_def_with_parent( + self.context.resolver.create_def_with_parent( self.parent, def_node_id, DefPathData::LifetimeNs(name.ident().name), @@ -1870,7 +1894,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None); - let opaque_ty_def_id = self.resolver.definitions().local_def_id(opaque_ty_node_id); + let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id); self.allocate_hir_id_counter(opaque_ty_node_id); diff --git a/src/librustc_hir/definitions.rs b/src/librustc_hir/definitions.rs index 5755a3db92ac1..c34607f8a94c6 100644 --- a/src/librustc_hir/definitions.rs +++ b/src/librustc_hir/definitions.rs @@ -8,14 +8,12 @@ pub use crate::def_id::DefPathHash; use crate::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::hir; -use rustc_ast::ast; use rustc_ast::crate_disambiguator::CrateDisambiguator; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; use rustc_index::vec::IndexVec; use rustc_span::hygiene::ExpnId; use rustc_span::symbol::{sym, Symbol}; -use rustc_span::Span; use log::debug; use std::fmt::Write; @@ -79,11 +77,6 @@ impl DefPathTable { pub struct Definitions { table: DefPathTable, - def_id_to_span: IndexVec, - - node_id_to_def_id: FxHashMap, - def_id_to_node_id: IndexVec, - // FIXME(eddyb) ideally all `LocalDefId`s would be HIR owners. pub(super) def_id_to_hir_id: IndexVec>, /// The reverse mapping of `def_id_to_hir_id`. @@ -95,11 +88,6 @@ pub struct Definitions { /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. expansions_that_defined: FxHashMap, 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, - /// Indices of unnamed struct or variant fields with unresolved attributes. - placeholder_field_indices: FxHashMap, } /// A unique identifier that we can use to lookup a definition @@ -319,16 +307,6 @@ impl Definitions { }) } - #[inline] - pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option { - self.node_id_to_def_id.get(&node).copied() - } - - #[inline] - pub fn local_def_id(&self, node: ast::NodeId) -> LocalDefId { - self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node)) - } - #[inline] pub fn as_local_hir_id(&self, def_id: LocalDefId) -> hir::HirId { self.local_def_id_to_hir_id(def_id) @@ -349,12 +327,6 @@ impl Definitions { self.hir_id_to_def_id.get(&hir_id).copied() } - /// Retrieves the span of the given `DefId` if `DefId` is in the local crate. - #[inline] - pub fn opt_span(&self, def_id: DefId) -> Option { - 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. pub fn create_root_def( &mut self, @@ -376,12 +348,6 @@ impl Definitions { 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); - - self.node_id_to_def_id.insert(ast::CRATE_NODE_ID, root); - self.set_invocation_parent(ExpnId::root(), root); - root } @@ -389,22 +355,12 @@ impl Definitions { pub fn create_def_with_parent( &mut self, parent: LocalDefId, - node_id: ast::NodeId, data: DefPathData, expn_id: ExpnId, - span: Span, ) -> LocalDefId { debug!( - "create_def_with_parent(parent={:?}, node_id={:?}, data={:?})", - parent, node_id, data - ); - - assert!( - !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_id_to_def_id[&node_id].local_def_index), + "create_def_with_parent(parent={:?}, data={:?}, expn_id={:?})", + parent, data, expn_id ); // The root node must be created with `create_root_def()`. @@ -431,17 +387,6 @@ impl Definitions { // Create the definition. 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 `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 `LocalDefId`. - if node_id != ast::DUMMY_NODE_ID { - 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(def_id, expn_id); } @@ -449,32 +394,24 @@ impl Definitions { def_id } - /// Initializes the `ast::NodeId` to `HirId` mapping once it has been generated during + /// Initializes the `LocalDefId` to `HirId` mapping once it has been generated during /// AST to HIR lowering. - pub fn init_node_id_to_hir_id_mapping( + pub fn init_def_id_to_hir_id_mapping( &mut self, - mapping: IndexVec>, + mapping: IndexVec>, ) { assert!( self.def_id_to_hir_id.is_empty(), "trying to initialize `LocalDefId` <-> `HirId` mappings twice" ); - self.def_id_to_hir_id = self - .def_id_to_node_id - .iter() - .map(|&node_id| mapping.get(node_id).and_then(|&hir_id| hir_id)) - .collect(); - // Build the reverse mapping of `def_id_to_hir_id`. self.hir_id_to_def_id = mapping - .into_iter_enumerated() - .filter_map(|(node_id, hir_id)| { - hir_id.and_then(|hir_id| { - self.node_id_to_def_id.get(&node_id).map(|&def_id| (hir_id, def_id)) - }) - }) + .iter_enumerated() + .filter_map(|(def_id, hir_id)| hir_id.map(|hir_id| (hir_id, def_id))) .collect(); + + self.def_id_to_hir_id = mapping; } pub fn expansion_that_defined(&self, id: LocalDefId) -> ExpnId { @@ -488,30 +425,6 @@ impl Definitions { 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) -> LocalDefId { - self.invocation_parents[&invoc_id] - } - - 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 `LocalDefId` is reset for an invocation"); - } - - pub fn placeholder_field_index(&self, node_id: ast::NodeId) -> usize { - self.placeholder_field_indices[&node_id] - } - - pub fn set_placeholder_field_index(&mut self, node_id: ast::NodeId, index: usize) { - let old_index = self.placeholder_field_indices.insert(node_id, index); - assert!(old_index.is_none(), "placeholder field index is reset for a node ID"); - } - - pub fn lint_node_id(&mut self, expn_id: ExpnId) -> ast::NodeId { - self.invocation_parents - .get(&expn_id) - .map_or(ast::CRATE_NODE_ID, |id| self.def_id_to_node_id[*id]) - } } impl DefPathData { diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 0dc007bbfd72f..2c80c846681a6 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -10,7 +10,7 @@ use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::Lrc; use rustc_errors::struct_span_err; use rustc_expand::base::SyntaxExtension; -use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; +use rustc_hir::def_id::{CrateNum, LocalDefId, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; use rustc_index::vec::IndexVec; use rustc_middle::middle::cstore::DepKind; @@ -896,6 +896,7 @@ impl<'a> CrateLoader<'a> { &mut self, item: &ast::Item, definitions: &Definitions, + def_id: LocalDefId, ) -> CrateNum { match item.kind { ast::ItemKind::ExternCrate(orig_name) => { @@ -918,7 +919,6 @@ impl<'a> CrateLoader<'a> { let cnum = self.resolve_crate(name, item.span, dep_kind, None); - let def_id = definitions.opt_local_def_id(item.id).unwrap(); let path_len = definitions.def_path(def_id).data.len(); self.update_extern_crate( cnum, diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index fa5c557b5d9c6..6f6104c3d6932 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -24,6 +24,7 @@ rustc_errors = { path = "../librustc_errors" } rustc_expand = { path = "../librustc_expand" } rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } +rustc_index = { path = "../librustc_index" } rustc_metadata = { path = "../librustc_metadata" } rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 8432e34a5271c..ef43f597eab47 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -19,6 +19,7 @@ use rustc_ast::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, use rustc_ast::ast::{AssocItem, AssocItemKind, MetaItemKind, StmtKind}; use rustc_ast::token::{self, Token}; use rustc_ast::visit::{self, AssocCtxt, Visitor}; +use rustc_ast_lowering::Resolver as ResolverAstLowering; use rustc_attr as attr; use rustc_data_structures::sync::Lrc; use rustc_errors::{struct_span_err, Applicability}; @@ -171,7 +172,7 @@ impl<'a> Resolver<'a> { fragment: &AstFragment, parent_scope: ParentScope<'a>, ) -> MacroRulesScope<'a> { - collect_definitions(&mut self.definitions, fragment, parent_scope.expansion); + collect_definitions(self, fragment, parent_scope.expansion); let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope }; fragment.visit_with(&mut visitor); visitor.parent_scope.macro_rules @@ -647,9 +648,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } else if orig_name == Some(kw::SelfLower) { self.r.graph_root } else { - let def_id = self.r.definitions.local_def_id(item.id); + let def_id = self.r.local_def_id(item.id); let crate_id = - self.r.crate_loader.process_extern_crate(item, &self.r.definitions); + self.r.crate_loader.process_extern_crate(item, &self.r.definitions, def_id); self.r.extern_crate_map.insert(def_id, crate_id); self.r.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }) }; @@ -704,7 +705,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { ItemKind::Mod(..) if ident.name == kw::Invalid => {} // Crate root ItemKind::Mod(..) => { - let def_id = self.r.definitions.local_def_id(item.id); + let def_id = self.r.local_def_id(item.id); let module_kind = ModuleKind::Def(DefKind::Mod, def_id.to_def_id(), ident.name); let module = self.r.arenas.alloc_module(ModuleData { no_implicit_prelude: parent.no_implicit_prelude || { @@ -727,18 +728,15 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { // These items live in the value namespace. ItemKind::Static(..) => { - let res = - Res::Def(DefKind::Static, self.r.definitions.local_def_id(item.id).to_def_id()); + let res = Res::Def(DefKind::Static, self.r.local_def_id(item.id).to_def_id()); self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion)); } ItemKind::Const(..) => { - let res = - Res::Def(DefKind::Const, self.r.definitions.local_def_id(item.id).to_def_id()); + let res = Res::Def(DefKind::Const, self.r.local_def_id(item.id).to_def_id()); self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion)); } ItemKind::Fn(..) => { - let res = - Res::Def(DefKind::Fn, self.r.definitions.local_def_id(item.id).to_def_id()); + let res = Res::Def(DefKind::Fn, self.r.local_def_id(item.id).to_def_id()); self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion)); // Functions introducing procedural macros reserve a slot @@ -748,15 +746,12 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { // These items live in the type namespace. ItemKind::TyAlias(..) => { - let res = Res::Def( - DefKind::TyAlias, - self.r.definitions.local_def_id(item.id).to_def_id(), - ); + let res = Res::Def(DefKind::TyAlias, self.r.local_def_id(item.id).to_def_id()); self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); } ItemKind::Enum(_, _) => { - let def_id = self.r.definitions.local_def_id(item.id).to_def_id(); + let def_id = self.r.local_def_id(item.id).to_def_id(); self.r.variant_vis.insert(def_id, vis); let module_kind = ModuleKind::Def(DefKind::Enum, def_id, ident.name); let module = self.r.new_module( @@ -771,17 +766,14 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } ItemKind::TraitAlias(..) => { - let res = Res::Def( - DefKind::TraitAlias, - self.r.definitions.local_def_id(item.id).to_def_id(), - ); + let res = Res::Def(DefKind::TraitAlias, self.r.local_def_id(item.id).to_def_id()); self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); } // These items live in both the type and value namespaces. ItemKind::Struct(ref vdata, _) => { // Define a name in the type namespace. - let def_id = self.r.definitions.local_def_id(item.id).to_def_id(); + let def_id = self.r.local_def_id(item.id).to_def_id(); let res = Res::Def(DefKind::Struct, def_id); self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); @@ -814,7 +806,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } let ctor_res = Res::Def( DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(vdata)), - self.r.definitions.local_def_id(ctor_node_id).to_def_id(), + self.r.local_def_id(ctor_node_id).to_def_id(), ); self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion)); self.r.struct_constructors.insert(def_id, (ctor_res, ctor_vis)); @@ -822,7 +814,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } ItemKind::Union(ref vdata, _) => { - let def_id = self.r.definitions.local_def_id(item.id).to_def_id(); + let def_id = self.r.local_def_id(item.id).to_def_id(); let res = Res::Def(DefKind::Union, def_id); self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); @@ -831,7 +823,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } ItemKind::Trait(..) => { - let def_id = self.r.definitions.local_def_id(item.id).to_def_id(); + let def_id = self.r.local_def_id(item.id).to_def_id(); // Add all the items within to a new module. let module_kind = ModuleKind::Def(DefKind::Trait, def_id, ident.name); @@ -856,18 +848,15 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { /// Constructs the reduced graph for one foreign item. fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem) { let (res, ns) = match item.kind { - ForeignItemKind::Fn(..) => ( - Res::Def(DefKind::Fn, self.r.definitions.local_def_id(item.id).to_def_id()), - ValueNS, - ), - ForeignItemKind::Static(..) => ( - Res::Def(DefKind::Static, self.r.definitions.local_def_id(item.id).to_def_id()), - ValueNS, - ), - ForeignItemKind::TyAlias(..) => ( - Res::Def(DefKind::ForeignTy, self.r.definitions.local_def_id(item.id).to_def_id()), - TypeNS, - ), + ForeignItemKind::Fn(..) => { + (Res::Def(DefKind::Fn, self.r.local_def_id(item.id).to_def_id()), ValueNS) + } + ForeignItemKind::Static(..) => { + (Res::Def(DefKind::Static, self.r.local_def_id(item.id).to_def_id()), ValueNS) + } + ForeignItemKind::TyAlias(..) => { + (Res::Def(DefKind::ForeignTy, self.r.local_def_id(item.id).to_def_id()), TypeNS) + } ForeignItemKind::MacCall(_) => unreachable!(), }; let parent = self.parent_scope.module; @@ -1170,7 +1159,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScope<'a> { let parent_scope = self.parent_scope; let expansion = parent_scope.expansion; - let def_id = self.r.definitions.local_def_id(item.id); + let def_id = self.r.local_def_id(item.id); let (ext, ident, span, macro_rules) = match &item.kind { ItemKind::MacroDef(def) => { let ext = Lrc::new(self.r.compile_macro(item, self.r.session.edition())); @@ -1315,7 +1304,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { } // Add the item to the trait info. - let item_def_id = self.r.definitions.local_def_id(item.id).to_def_id(); + let item_def_id = self.r.local_def_id(item.id).to_def_id(); let (res, ns) = match item.kind { AssocItemKind::Const(..) => (Res::Def(DefKind::AssocConst, item_def_id), ValueNS), AssocItemKind::Fn(_, ref sig, _, _) => { @@ -1417,7 +1406,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { let ident = variant.ident; // Define a name in the type namespace. - let def_id = self.r.definitions.local_def_id(variant.id).to_def_id(); + let def_id = self.r.local_def_id(variant.id).to_def_id(); let res = Res::Def(DefKind::Variant, def_id); self.r.define(parent, ident, TypeNS, (res, vis, variant.span, expn_id)); @@ -1435,7 +1424,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { // It's ok to use the variant's id as a ctor id since an // error will be reported on any use of such resolution anyway. let ctor_node_id = variant.data.ctor_id().unwrap_or(variant.id); - let ctor_def_id = self.r.definitions.local_def_id(ctor_node_id).to_def_id(); + let ctor_def_id = self.r.local_def_id(ctor_node_id).to_def_id(); let ctor_kind = CtorKind::from_ast(&variant.data); let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id); self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id)); diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index cc0e97aeb1430..0ca01a384e73e 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -29,6 +29,7 @@ use crate::Resolver; use rustc_ast::ast; use rustc_ast::node_id::NodeMap; use rustc_ast::visit::{self, Visitor}; +use rustc_ast_lowering::Resolver as ResolverAstLowering; use rustc_data_structures::fx::FxHashSet; use rustc_errors::pluralize; use rustc_middle::ty; @@ -64,7 +65,7 @@ impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> { fn check_import(&mut self, id: ast::NodeId) { let mut used = false; self.r.per_ns(|this, ns| used |= this.used_imports.contains(&(id, ns))); - let def_id = self.r.definitions.local_def_id(id); + let def_id = self.r.local_def_id(id); if !used { if self.r.maybe_unused_trait_imports.contains(&def_id) { // Check later. @@ -246,7 +247,7 @@ impl Resolver<'_> { } } ImportKind::ExternCrate { .. } => { - let def_id = self.definitions.local_def_id(import.id); + let def_id = self.local_def_id(import.id); self.maybe_unused_extern_crates.push((def_id, import.span)); } ImportKind::MacroUse => { diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs index 71cedb208fcf2..7bf039ea8a53e 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/src/librustc_resolve/def_collector.rs @@ -1,8 +1,10 @@ +use crate::Resolver; use log::debug; use rustc_ast::ast::*; use rustc_ast::token::{self, Token}; use rustc_ast::visit::{self, FnKind}; use rustc_ast::walk_list; +use rustc_ast_lowering::Resolver as ResolverAstLowering; use rustc_expand::expand::AstFragment; use rustc_hir::def_id::LocalDefId; use rustc_hir::definitions::*; @@ -11,26 +13,26 @@ use rustc_span::symbol::{kw, sym}; use rustc_span::Span; crate fn collect_definitions( - definitions: &mut Definitions, + resolver: &mut Resolver<'_>, fragment: &AstFragment, expansion: ExpnId, ) { - let parent_def = definitions.invocation_parent(expansion); - fragment.visit_with(&mut DefCollector { definitions, parent_def, expansion }); + let parent_def = resolver.invocation_parents[&expansion]; + fragment.visit_with(&mut DefCollector { resolver, parent_def, expansion }); } /// Creates `DefId`s for nodes in the AST. -struct DefCollector<'a> { - definitions: &'a mut Definitions, +struct DefCollector<'a, 'b> { + resolver: &'a mut Resolver<'b>, parent_def: LocalDefId, expansion: ExpnId, } -impl<'a> DefCollector<'a> { +impl<'a, 'b> DefCollector<'a, 'b> { fn create_def(&mut self, node_id: NodeId, data: DefPathData, span: Span) -> LocalDefId { let parent_def = self.parent_def; debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); - self.definitions.create_def_with_parent(parent_def, node_id, data, self.expansion, span) + self.resolver.create_def_with_parent(parent_def, node_id, data, self.expansion, span) } fn with_parent(&mut self, parent_def: LocalDefId, f: F) { @@ -43,12 +45,13 @@ impl<'a> DefCollector<'a> { let index = |this: &Self| { index.unwrap_or_else(|| { let node_id = NodeId::placeholder_from_expn_id(this.expansion); - this.definitions.placeholder_field_index(node_id) + this.resolver.placeholder_field_indices[&node_id] }) }; if field.is_placeholder { - self.definitions.set_placeholder_field_index(field.id, index(self)); + let old_index = self.resolver.placeholder_field_indices.insert(field.id, index(self)); + assert!(old_index.is_none(), "placeholder field index is reset for a node ID"); self.visit_macro_invoc(field.id); } else { let name = field.ident.map_or_else(|| sym::integer(index(self)), |ident| ident.name); @@ -58,11 +61,13 @@ impl<'a> DefCollector<'a> { } fn visit_macro_invoc(&mut self, id: NodeId) { - self.definitions.set_invocation_parent(id.placeholder_to_expn_id(), self.parent_def); + let old_parent = + self.resolver.invocation_parents.insert(id.placeholder_to_expn_id(), self.parent_def); + assert!(old_parent.is_none(), "parent `LocalDefId` is reset for an invocation"); } } -impl<'a> visit::Visitor<'a> for DefCollector<'a> { +impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { fn visit_item(&mut self, i: &'a Item) { debug!("visit_item: {:?}", i); diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index bd2ce5a72e8d9..35d71a38bbe0d 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -107,7 +107,7 @@ impl<'a> Resolver<'a> { match outer_res { Res::SelfTy(maybe_trait_defid, maybe_impl_defid) => { if let Some(impl_span) = - maybe_impl_defid.and_then(|def_id| self.definitions.opt_span(def_id)) + maybe_impl_defid.and_then(|def_id| self.opt_span(def_id)) { err.span_label( reduce_impl_span_to_impl_keyword(sm, impl_span), @@ -126,12 +126,12 @@ impl<'a> Resolver<'a> { return err; } Res::Def(DefKind::TyParam, def_id) => { - if let Some(span) = self.definitions.opt_span(def_id) { + if let Some(span) = self.opt_span(def_id) { err.span_label(span, "type parameter from outer function"); } } Res::Def(DefKind::ConstParam, def_id) => { - if let Some(span) = self.definitions.opt_span(def_id) { + if let Some(span) = self.opt_span(def_id) { err.span_label(span, "const parameter from outer function"); } } @@ -825,7 +825,7 @@ impl<'a> Resolver<'a> { Applicability::MaybeIncorrect, ); let def_span = suggestion.res.opt_def_id().and_then(|def_id| match def_id.krate { - LOCAL_CRATE => self.definitions.opt_span(def_id), + LOCAL_CRATE => self.opt_span(def_id), _ => Some( self.session .source_map() diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index 74a8b7e2f556d..8a6541b399e38 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -12,6 +12,7 @@ use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBindin use rustc_ast::ast::NodeId; use rustc_ast::unwrap_or; use rustc_ast::util::lev_distance::find_best_match_for_name; +use rustc_ast_lowering::Resolver as ResolverAstLowering; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::ptr_key::PtrKey; use rustc_errors::{pluralize, struct_span_err, Applicability}; @@ -1393,7 +1394,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let is_good_import = binding.is_import() && !binding.is_ambiguity() && !ident.span.from_expansion(); if is_good_import || binding.is_macro_def() { - let res = binding.res().map_id(|id| this.definitions.local_def_id(id)); + let res = binding.res().map_id(|id| this.local_def_id(id)); if res != def::Res::Err { reexports.push(Export { ident, res, span: binding.span, vis: binding.vis }); } diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 61f20df8cc6c0..6f769c3c59cae 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -16,6 +16,7 @@ use rustc_ast::ptr::P; use rustc_ast::util::lev_distance::find_best_match_for_name; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use rustc_ast::{unwrap_or, walk_list}; +use rustc_ast_lowering::Resolver as ResolverAstLowering; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::DiagnosticId; use rustc_hir::def::Namespace::{self, *}; @@ -707,7 +708,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { } fn with_scope(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T { - let id = self.r.definitions.local_def_id(id); + let id = self.r.local_def_id(id); let module = self.r.module_map.get(&id).cloned(); // clones a reference if let Some(module) = module { // Move down in the graph. @@ -759,7 +760,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { debug!("resolve_adt"); self.with_current_self_item(item, |this| { this.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { - let item_def_id = this.r.definitions.local_def_id(item.id).to_def_id(); + let item_def_id = this.r.local_def_id(item.id).to_def_id(); this.with_self_rib(Res::SelfTy(None, Some(item_def_id)), |this| { visit::walk_item(this, item); }); @@ -839,7 +840,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => { // Create a new rib for the trait-wide type parameters. self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { - let local_def_id = this.r.definitions.local_def_id(item.id).to_def_id(); + let local_def_id = this.r.local_def_id(item.id).to_def_id(); this.with_self_rib(Res::SelfTy(Some(local_def_id), None), |this| { this.visit_generics(generics); walk_list!(this, visit_param_bound, bounds); @@ -880,7 +881,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ItemKind::TraitAlias(ref generics, ref bounds) => { // Create a new rib for the trait-wide type parameters. self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| { - let local_def_id = this.r.definitions.local_def_id(item.id).to_def_id(); + let local_def_id = this.r.local_def_id(item.id).to_def_id(); this.with_self_rib(Res::SelfTy(Some(local_def_id), None), |this| { this.visit_generics(generics); walk_list!(this, visit_param_bound, bounds); @@ -961,7 +962,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { seen_bindings.entry(ident).or_insert(param.ident.span); // Plain insert (no renaming). - let res = Res::Def(def_kind, self.r.definitions.local_def_id(param.id).to_def_id()); + let res = Res::Def(def_kind, self.r.local_def_id(param.id).to_def_id()); match param.kind { GenericParamKind::Type { .. } => { @@ -1111,7 +1112,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.with_self_rib(Res::SelfTy(None, None), |this| { // Resolve the trait reference, if necessary. this.with_optional_trait_ref(opt_trait_reference.as_ref(), |this, trait_id| { - let item_def_id = this.r.definitions.local_def_id(item_id).to_def_id(); + let item_def_id = this.r.local_def_id(item_id).to_def_id(); this.with_self_rib(Res::SelfTy(trait_id, Some(item_def_id)), |this| { if let Some(trait_ref) = opt_trait_reference.as_ref() { // Resolve type arguments in the trait path. @@ -2002,7 +2003,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { if let StmtKind::Item(ref item) = stmt.kind { if let ItemKind::MacroDef(..) = item.kind { num_macro_definition_ribs += 1; - let res = self.r.definitions.local_def_id(item.id).to_def_id(); + let res = self.r.local_def_id(item.id).to_def_id(); self.ribs[ValueNS].push(Rib::new(MacroDefinition(res))); self.label_ribs.push(Rib::new(MacroDefinition(res))); } @@ -2296,7 +2297,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ) -> SmallVec<[LocalDefId; 1]> { let mut import_ids = smallvec![]; while let NameBindingKind::Import { import, binding, .. } = kind { - let id = self.r.definitions.local_def_id(import.id); + let id = self.r.local_def_id(import.id); self.r.maybe_unused_trait_imports.insert(id); self.r.add_to_glob_map(&import, trait_name); import_ids.push(id); diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index 05ef0aa0bb689..79c544ec6cc94 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -512,7 +512,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { _ => {} } if !suggested { - if let Some(span) = self.r.definitions.opt_span(def_id) { + if let Some(span) = self.r.opt_span(def_id) { err.span_label(span, &format!("`{}` defined here", path_str)); } err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", path_str)); @@ -536,7 +536,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { if nightly_options::is_nightly_build() { let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a \ `type` alias"; - if let Some(span) = self.r.definitions.opt_span(def_id) { + if let Some(span) = self.r.opt_span(def_id) { err.span_help(span, msg); } else { err.help(msg); @@ -593,7 +593,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { bad_struct_syntax_suggestion(def_id); } (Res::Def(DefKind::Ctor(_, CtorKind::Fn), def_id), _) if ns == ValueNS => { - if let Some(span) = self.r.definitions.opt_span(def_id) { + if let Some(span) = self.r.opt_span(def_id) { err.span_label(span, &format!("`{}` defined here", path_str)); } err.span_label(span, format!("did you mean `{}( /* fields */ )`?", path_str)); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 91bd155614178..0aca5c4905df9 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -27,6 +27,7 @@ use rustc_ast::attr; use rustc_ast::node_id::NodeMap; use rustc_ast::unwrap_or; use rustc_ast::visit::{self, Visitor}; +use rustc_ast_lowering::Resolver as ResolverAstLowering; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::ptr_key::PtrKey; @@ -36,9 +37,10 @@ use rustc_expand::base::SyntaxExtension; use rustc_hir::def::Namespace::*; use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX}; -use rustc_hir::definitions::{DefKey, Definitions}; +use rustc_hir::definitions::{DefKey, DefPathData, Definitions}; use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint}; use rustc_hir::TraitCandidate; +use rustc_index::vec::IndexVec; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::hir::exports::ExportMap; use rustc_middle::middle::cstore::{CrateStore, MetadataLoaderDyn}; @@ -256,31 +258,21 @@ impl<'a> From<&'a ast::PathSegment> for Segment { } } -struct UsePlacementFinder<'d> { - definitions: &'d Definitions, - target_module: LocalDefId, +struct UsePlacementFinder { + target_module: NodeId, span: Option, found_use: bool, } -impl<'d> UsePlacementFinder<'d> { - fn check( - definitions: &'d Definitions, - krate: &Crate, - target_module: DefId, - ) -> (Option, bool) { - if let Some(target_module) = target_module.as_local() { - let mut finder = - UsePlacementFinder { definitions, target_module, span: None, found_use: false }; - visit::walk_crate(&mut finder, krate); - (finder.span, finder.found_use) - } else { - (None, false) - } +impl UsePlacementFinder { + fn check(krate: &Crate, target_module: NodeId) -> (Option, bool) { + let mut finder = UsePlacementFinder { target_module, span: None, found_use: false }; + visit::walk_crate(&mut finder, krate); + (finder.span, finder.found_use) } } -impl<'tcx, 'd> Visitor<'tcx> for UsePlacementFinder<'d> { +impl<'tcx> Visitor<'tcx> for UsePlacementFinder { fn visit_mod( &mut self, module: &'tcx ast::Mod, @@ -291,7 +283,7 @@ impl<'tcx, 'd> Visitor<'tcx> for UsePlacementFinder<'d> { if self.span.is_some() { return; } - if self.definitions.local_def_id(node_id) != self.target_module { + if node_id != self.target_module { visit::walk_mod(self, module); return; } @@ -979,6 +971,17 @@ pub struct Resolver<'a> { lint_buffer: LintBuffer, next_node_id: NodeId, + + def_id_to_span: IndexVec, + + node_id_to_def_id: FxHashMap, + def_id_to_node_id: IndexVec, + + /// Indices of unnamed struct or variant fields with unresolved attributes. + placeholder_field_indices: FxHashMap, + /// 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, } /// Nothing really interesting here; it just provides memory for the rest of the crate. @@ -1042,7 +1045,7 @@ impl<'a, 'b> DefIdTree for &'a Resolver<'b> { /// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that /// the resolver is no longer needed as all the relevant information is inline. -impl rustc_ast_lowering::Resolver for Resolver<'_> { +impl ResolverAstLowering for Resolver<'_> { fn def_key(&mut self, id: DefId) -> DefKey { if let Some(id) = id.as_local() { self.definitions().def_key(id) @@ -1113,6 +1116,47 @@ impl rustc_ast_lowering::Resolver for Resolver<'_> { fn trait_map(&self) -> &NodeMap> { &self.trait_map } + + fn opt_local_def_id(&self, node: NodeId) -> Option { + self.node_id_to_def_id.get(&node).copied() + } + + fn local_def_id(&self, node: NodeId) -> LocalDefId { + self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node)) + } + + /// Adds a definition with a parent definition. + fn create_def_with_parent( + &mut self, + parent: LocalDefId, + node_id: ast::NodeId, + data: DefPathData, + expn_id: ExpnId, + span: Span, + ) -> LocalDefId { + assert!( + !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.definitions.def_key(self.node_id_to_def_id[&node_id]), + ); + + let def_id = self.definitions.create_def_with_parent(parent, data, expn_id); + + assert_eq!(self.def_id_to_span.push(span), def_id); + + // 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 `LocalDefId`. + if node_id != ast::DUMMY_NODE_ID { + 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); + } + assert_eq!(self.def_id_to_node_id.push(node_id), def_id); + + def_id + } } impl<'a> Resolver<'a> { @@ -1144,7 +1188,17 @@ impl<'a> Resolver<'a> { module_map.insert(LocalDefId { local_def_index: CRATE_DEF_INDEX }, graph_root); let mut definitions = Definitions::default(); - definitions.create_root_def(crate_name, session.local_crate_disambiguator()); + let root = definitions.create_root_def(crate_name, session.local_crate_disambiguator()); + + let mut def_id_to_span = IndexVec::default(); + assert_eq!(def_id_to_span.push(rustc_span::DUMMY_SP), root); + let mut def_id_to_node_id = IndexVec::default(); + assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), root); + let mut node_id_to_def_id = FxHashMap::default(); + node_id_to_def_id.insert(CRATE_NODE_ID, root); + + let mut invocation_parents = FxHashMap::default(); + invocation_parents.insert(ExpnId::root(), root); let mut extern_prelude: FxHashMap> = session .opts @@ -1263,6 +1317,11 @@ impl<'a> Resolver<'a> { variant_vis: Default::default(), lint_buffer: LintBuffer::default(), next_node_id: NodeId::from_u32(1), + def_id_to_span, + node_id_to_def_id, + def_id_to_node_id, + placeholder_field_indices: Default::default(), + invocation_parents, } } @@ -1457,7 +1516,7 @@ impl<'a> Resolver<'a> { #[inline] fn add_to_glob_map(&mut self, import: &Import<'_>, ident: Ident) { if import.is_glob() { - let def_id = self.definitions.local_def_id(import.id); + let def_id = self.local_def_id(import.id); self.glob_map.entry(def_id).or_default().insert(ident.name); } } @@ -2538,7 +2597,11 @@ impl<'a> Resolver<'a> { for UseError { mut err, candidates, def_id, instead, suggestion } in self.use_injections.drain(..) { - let (span, found_use) = UsePlacementFinder::check(&self.definitions, krate, def_id); + let (span, found_use) = if let Some(def_id) = def_id.as_local() { + UsePlacementFinder::check(krate, self.def_id_to_node_id[def_id]) + } else { + (None, false) + }; if !candidates.is_empty() { diagnostics::show_candidates(&mut err, span, &candidates, instead, found_use); } else if let Some((span, msg, sugg, appl)) = suggestion { @@ -2934,6 +2997,12 @@ impl<'a> Resolver<'a> { pub fn all_macros(&self) -> &FxHashMap { &self.all_macros } + + /// Retrieves the span of the given `DefId` if `DefId` is in the local crate. + #[inline] + pub fn opt_span(&self, def_id: DefId) -> Option { + if let Some(def_id) = def_id.as_local() { Some(self.def_id_to_span[def_id]) } else { None } + } } fn names_to_string(names: &[Symbol]) -> String { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 1b49722355e54..398b0e92d9d8c 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -7,6 +7,7 @@ use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy}; use crate::{CrateLint, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Weak}; use crate::{ModuleKind, ModuleOrUniformRoot, NameBinding, PathResult, Segment, ToNameBinding}; use rustc_ast::ast::{self, NodeId}; +use rustc_ast_lowering::Resolver as ResolverAstLowering; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, StabilityLevel}; use rustc_data_structures::fx::FxHashSet; @@ -190,7 +191,7 @@ impl<'a> base::Resolver for Resolver<'a> { ))); let parent_scope = if let Some(module_id) = parent_module_id { - let parent_def_id = self.definitions.local_def_id(module_id); + let parent_def_id = self.local_def_id(module_id); self.definitions.add_parent_module_of_macro_def(expn_id, parent_def_id.to_def_id()); self.module_map[&parent_def_id] } else { @@ -340,7 +341,9 @@ impl<'a> base::Resolver for Resolver<'a> { } fn lint_node_id(&mut self, expn_id: ExpnId) -> NodeId { - self.definitions.lint_node_id(expn_id) + self.invocation_parents + .get(&expn_id) + .map_or(ast::CRATE_NODE_ID, |id| self.def_id_to_node_id[*id]) } fn has_derive_copy(&self, expn_id: ExpnId) -> bool { From 1d3f49f53654f12cf9f3501666c0dfd1afe5cf8b Mon Sep 17 00:00:00 2001 From: marmeladema Date: Sun, 21 Jun 2020 15:49:38 +0100 Subject: [PATCH 2/3] Always create a root definition when creating a new `Definitions` object. --- src/librustc_ast_lowering/lib.rs | 14 +++++----- src/librustc_hir/definitions.rs | 40 +++++++++++++++------------ src/librustc_interface/passes.rs | 5 +++- src/librustc_resolve/def_collector.rs | 2 +- src/librustc_resolve/lib.rs | 10 +++---- 5 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index ac8a229da43db..39b14ac458832 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -210,7 +210,7 @@ pub trait Resolver { fn local_def_id(&self, node: NodeId) -> LocalDefId; - fn create_def_with_parent( + fn create_def( &mut self, parent: LocalDefId, node_id: ast::NodeId, @@ -449,7 +449,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { match tree.kind { UseTreeKind::Simple(_, id1, id2) => { for &id in &[id1, id2] { - self.lctx.resolver.create_def_with_parent( + self.lctx.resolver.create_def( owner, id, DefPathData::Misc, @@ -696,7 +696,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { *local_id_counter += 1; let owner = this.resolver.opt_local_def_id(owner).expect( - "you forgot to call `create_def_with_parent` or are lowering node-IDs \ + "you forgot to call `create_def` or are lowering node-IDs \ that do not belong to the current owner", ); @@ -824,7 +824,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; // Add a definition for the in-band lifetime def. - self.resolver.create_def_with_parent( + self.resolver.create_def( parent_def_id, node_id, DefPathData::LifetimeNs(str_name), @@ -1112,7 +1112,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let impl_trait_node_id = self.resolver.next_node_id(); let parent_def_id = self.current_hir_id_owner.last().unwrap().0; - self.resolver.create_def_with_parent( + self.resolver.create_def( parent_def_id, impl_trait_node_id, DefPathData::ImplTrait, @@ -1178,7 +1178,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let node_id = self.resolver.next_node_id(); // Add a definition for the in-band const def. - self.resolver.create_def_with_parent( + self.resolver.create_def( parent_def_id, node_id, DefPathData::AnonConst, @@ -1644,7 +1644,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let def_node_id = self.context.resolver.next_node_id(); let hir_id = self.context.lower_node_id_with_owner(def_node_id, self.opaque_ty_id); - self.context.resolver.create_def_with_parent( + self.context.resolver.create_def( self.parent, def_node_id, DefPathData::LifetimeNs(name.ident().name), diff --git a/src/librustc_hir/definitions.rs b/src/librustc_hir/definitions.rs index c34607f8a94c6..5e072d37eaad4 100644 --- a/src/librustc_hir/definitions.rs +++ b/src/librustc_hir/definitions.rs @@ -71,9 +71,9 @@ impl DefPathTable { } /// The definition table containing node definitions. -/// It holds the `DefPathTable` for local `DefId`s/`DefPath`s and it also stores a -/// mapping from `NodeId`s to local `DefId`s. -#[derive(Clone, Default)] +/// It holds the `DefPathTable` for `LocalDefId`s/`DefPath`s. +/// It also stores mappings to convert `LocalDefId`s to/from `HirId`s. +#[derive(Clone)] pub struct Definitions { table: DefPathTable, @@ -328,11 +328,7 @@ impl Definitions { } /// Adds a root definition (no parent) and a few other reserved definitions. - pub fn create_root_def( - &mut self, - crate_name: &str, - crate_disambiguator: CrateDisambiguator, - ) -> LocalDefId { + pub fn new(crate_name: &str, crate_disambiguator: CrateDisambiguator) -> Definitions { let key = DefKey { parent: None, disambiguated_data: DisambiguatedDefPathData { @@ -344,24 +340,34 @@ impl Definitions { let parent_hash = DefKey::root_parent_stable_hash(crate_name, crate_disambiguator); let def_path_hash = key.compute_stable_hash(parent_hash); - // Create the definition. - let root = LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) }; + // Create the root definition. + let mut table = DefPathTable::default(); + let root = LocalDefId { local_def_index: table.allocate(key, def_path_hash) }; assert_eq!(root.local_def_index, CRATE_DEF_INDEX); - root + Definitions { + table, + def_id_to_hir_id: Default::default(), + hir_id_to_def_id: Default::default(), + expansions_that_defined: Default::default(), + next_disambiguator: Default::default(), + parent_modules_of_macro_defs: Default::default(), + } + } + + /// Retrieves the root definition. + pub fn get_root_def(&self) -> LocalDefId { + LocalDefId { local_def_index: CRATE_DEF_INDEX } } /// Adds a definition with a parent definition. - pub fn create_def_with_parent( + pub fn create_def( &mut self, parent: LocalDefId, data: DefPathData, expn_id: ExpnId, ) -> LocalDefId { - debug!( - "create_def_with_parent(parent={:?}, data={:?}, expn_id={:?})", - parent, data, expn_id - ); + debug!("create_def(parent={:?}, data={:?}, expn_id={:?})", parent, data, expn_id); // The root node must be created with `create_root_def()`. assert!(data != DefPathData::CrateRoot); @@ -382,7 +388,7 @@ impl Definitions { 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); + debug!("create_def: after disambiguation, key = {:?}", key); // Create the definition. let def_id = LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) }; diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 1ed9bc3f1f509..ea3b19ab4a75d 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -734,7 +734,10 @@ pub fn create_global_ctxt<'tcx>( arena: &'tcx WorkerLocal>, ) -> QueryContext<'tcx> { let sess = &compiler.session(); - let defs: &'tcx Definitions = arena.alloc(mem::take(&mut resolver_outputs.definitions)); + let defs: &'tcx Definitions = arena.alloc(mem::replace( + &mut resolver_outputs.definitions, + Definitions::new(crate_name, sess.local_crate_disambiguator()), + )); let query_result_on_disk_cache = rustc_incremental::load_query_result_cache(sess); diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs index 7bf039ea8a53e..f1063f42c91ec 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/src/librustc_resolve/def_collector.rs @@ -32,7 +32,7 @@ impl<'a, 'b> DefCollector<'a, 'b> { fn create_def(&mut self, node_id: NodeId, data: DefPathData, span: Span) -> LocalDefId { let parent_def = self.parent_def; debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); - self.resolver.create_def_with_parent(parent_def, node_id, data, self.expansion, span) + self.resolver.create_def(parent_def, node_id, data, self.expansion, span) } fn with_parent(&mut self, parent_def: LocalDefId, f: F) { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0aca5c4905df9..6005f009cc3d5 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1126,7 +1126,7 @@ impl ResolverAstLowering for Resolver<'_> { } /// Adds a definition with a parent definition. - fn create_def_with_parent( + fn create_def( &mut self, parent: LocalDefId, node_id: ast::NodeId, @@ -1142,7 +1142,7 @@ impl ResolverAstLowering for Resolver<'_> { self.definitions.def_key(self.node_id_to_def_id[&node_id]), ); - let def_id = self.definitions.create_def_with_parent(parent, data, expn_id); + let def_id = self.definitions.create_def(parent, data, expn_id); assert_eq!(self.def_id_to_span.push(span), def_id); @@ -1150,7 +1150,7 @@ impl ResolverAstLowering for Resolver<'_> { // anything in the AST, so they don't have a `NodeId`. For these cases // we don't need a mapping from `NodeId` to `LocalDefId`. if node_id != ast::DUMMY_NODE_ID { - debug!("create_def_with_parent: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); + debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); self.node_id_to_def_id.insert(node_id, def_id); } assert_eq!(self.def_id_to_node_id.push(node_id), def_id); @@ -1187,8 +1187,8 @@ impl<'a> Resolver<'a> { let mut module_map = FxHashMap::default(); module_map.insert(LocalDefId { local_def_index: CRATE_DEF_INDEX }, graph_root); - let mut definitions = Definitions::default(); - let root = definitions.create_root_def(crate_name, session.local_crate_disambiguator()); + let definitions = Definitions::new(crate_name, session.local_crate_disambiguator()); + let root = definitions.get_root_def(); let mut def_id_to_span = IndexVec::default(); assert_eq!(def_id_to_span.push(rustc_span::DUMMY_SP), root); From bd4f6f0b7d88baa9a5ecb18a2a700978ddcd58ff Mon Sep 17 00:00:00 2001 From: marmeladema Date: Sun, 21 Jun 2020 23:49:06 +0100 Subject: [PATCH 3/3] Move `next_disambiguator` to `Resolver` --- src/librustc_hir/definitions.rs | 12 ++---------- src/librustc_resolve/lib.rs | 14 +++++++++++++- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/librustc_hir/definitions.rs b/src/librustc_hir/definitions.rs index 5e072d37eaad4..79b7068273932 100644 --- a/src/librustc_hir/definitions.rs +++ b/src/librustc_hir/definitions.rs @@ -87,7 +87,6 @@ pub struct Definitions { parent_modules_of_macro_defs: FxHashMap, /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. expansions_that_defined: FxHashMap, - next_disambiguator: FxHashMap<(LocalDefId, DefPathData), u32>, } /// A unique identifier that we can use to lookup a definition @@ -350,7 +349,6 @@ impl Definitions { def_id_to_hir_id: Default::default(), hir_id_to_def_id: Default::default(), expansions_that_defined: Default::default(), - next_disambiguator: Default::default(), parent_modules_of_macro_defs: Default::default(), } } @@ -366,20 +364,14 @@ impl Definitions { parent: LocalDefId, data: DefPathData, expn_id: ExpnId, + mut next_disambiguator: impl FnMut(LocalDefId, DefPathData) -> u32, ) -> LocalDefId { debug!("create_def(parent={:?}, data={:?}, expn_id={:?})", parent, data, expn_id); // The root node must be created with `create_root_def()`. assert!(data != DefPathData::CrateRoot); - // Find the next free disambiguator for this key. - let disambiguator = { - let next_disamb = self.next_disambiguator.entry((parent, data)).or_insert(0); - let disambiguator = *next_disamb; - *next_disamb = next_disamb.checked_add(1).expect("disambiguator overflow"); - disambiguator - }; - + let disambiguator = next_disambiguator(parent, data); let key = DefKey { parent: Some(parent.local_def_index), disambiguated_data: DisambiguatedDefPathData { data, disambiguator }, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 6005f009cc3d5..ce068b8ac69a4 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -982,6 +982,8 @@ pub struct Resolver<'a> { /// 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, + + next_disambiguator: FxHashMap<(LocalDefId, DefPathData), u32>, } /// Nothing really interesting here; it just provides memory for the rest of the crate. @@ -1142,7 +1144,16 @@ impl ResolverAstLowering for Resolver<'_> { self.definitions.def_key(self.node_id_to_def_id[&node_id]), ); - let def_id = self.definitions.create_def(parent, data, expn_id); + // Find the next free disambiguator for this key. + let next_disambiguator = &mut self.next_disambiguator; + let next_disambiguator = |parent, data| { + let next_disamb = next_disambiguator.entry((parent, data)).or_insert(0); + let disambiguator = *next_disamb; + *next_disamb = next_disamb.checked_add(1).expect("disambiguator overflow"); + disambiguator + }; + + let def_id = self.definitions.create_def(parent, data, expn_id, next_disambiguator); assert_eq!(self.def_id_to_span.push(span), def_id); @@ -1322,6 +1333,7 @@ impl<'a> Resolver<'a> { def_id_to_node_id, placeholder_field_indices: Default::default(), invocation_parents, + next_disambiguator: Default::default(), } }