From 34e4d72929c33bb126e0b1b199faab9031e0f3de Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 30 May 2022 18:49:17 +0200 Subject: [PATCH] Separate `source_span` and `expn_that_defined` from `Definitions`. --- compiler/rustc_ast_lowering/src/asm.rs | 10 +--- compiler/rustc_ast_lowering/src/expr.rs | 9 +-- compiler/rustc_ast_lowering/src/lib.rs | 48 +++++----------- compiler/rustc_hir/src/definitions.rs | 56 ++----------------- compiler/rustc_middle/src/hir/map/mod.rs | 5 +- compiler/rustc_middle/src/hir/mod.rs | 7 ++- compiler/rustc_middle/src/query/mod.rs | 3 - compiler/rustc_middle/src/ty/context.rs | 50 +++++++++++++++-- compiler/rustc_middle/src/ty/mod.rs | 6 +- .../rustc_query_impl/src/on_disk_cache.rs | 5 +- compiler/rustc_query_system/src/ich/hcx.rs | 11 +++- compiler/rustc_resolve/src/diagnostics.rs | 21 +++---- compiler/rustc_resolve/src/lib.rs | 39 +++++++++++-- 13 files changed, 135 insertions(+), 135 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 1a125a9751b..aab9b90e4b7 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -11,7 +11,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::definitions::DefPathData; use rustc_session::parse::feature_err; -use rustc_span::{sym, ExpnId, Span}; +use rustc_span::{sym, Span}; use rustc_target::asm; use std::collections::hash_map::Entry; use std::fmt::Write; @@ -243,13 +243,7 @@ pub(crate) fn lower_inline_asm( // Wrap the expression in an AnonConst. let parent_def_id = self.current_hir_id_owner; let node_id = self.next_node_id(); - self.create_def( - parent_def_id, - node_id, - DefPathData::AnonConst, - ExpnId::root(), - *op_sp, - ); + self.create_def(parent_def_id, node_id, DefPathData::AnonConst); let anon_const = AnonConst { id: node_id, value: P(expr) }; hir::InlineAsmOperand::SymFn { anon_const: self.lower_anon_const(&anon_const), diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 619debba6da..d6b27f267e0 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -11,7 +11,6 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::definitions::DefPathData; -use rustc_span::hygiene::ExpnId; use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; use rustc_span::symbol::{sym, Ident}; use rustc_span::DUMMY_SP; @@ -358,13 +357,7 @@ fn lower_legacy_const_generics( let node_id = self.next_node_id(); // Add a definition for the in-band const def. - self.create_def( - parent_def_id, - node_id, - DefPathData::AnonConst, - ExpnId::root(), - arg.span, - ); + self.create_def(parent_def_id, node_id, DefPathData::AnonConst); let anon_const = AnonConst { id: node_id, value: arg }; generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const))); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 6903e02f3a5..d56b2fd5d0b 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -61,7 +61,7 @@ use rustc_session::cstore::CrateStoreDyn; use rustc_session::parse::feature_err; use rustc_session::Session; -use rustc_span::hygiene::{ExpnId, MacroKind}; +use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DesugaringKind; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -391,6 +391,7 @@ fn compute_hir_hash( sess: &Session, definitions: &Definitions, cstore: &CrateStoreDyn, + resolver: &ResolverOutputs, owners: &IndexVec>>, ) -> Fingerprint { let mut hir_body_nodes: Vec<_> = owners @@ -404,7 +405,7 @@ fn compute_hir_hash( hir_body_nodes.sort_unstable_by_key(|bn| bn.0); let mut stable_hasher = StableHasher::new(); - let mut hcx = StableHashingContext::new(sess, definitions, cstore); + let mut hcx = StableHashingContext::new(sess, definitions, cstore, &resolver.source_span); hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher); stable_hasher.finish() } @@ -437,7 +438,7 @@ pub fn lower_crate<'hir>( .lower_node(def_id); } - let hir_hash = compute_hir_hash(sess, definitions, cstore, &owners); + let hir_hash = compute_hir_hash(sess, definitions, cstore, resolver, &owners); let krate = hir::Crate { owners, hir_hash }; arena.alloc(krate) } @@ -459,7 +460,12 @@ enum ParenthesizedGenericArgs { impl<'a, 'hir> LoweringContext<'a, 'hir> { fn create_stable_hashing_context(&self) -> StableHashingContext<'_> { - StableHashingContext::new(self.sess, self.definitions, self.cstore) + StableHashingContext::new( + self.sess, + self.definitions, + self.cstore, + &self.resolver.source_span, + ) } fn create_def( @@ -467,8 +473,6 @@ fn create_def( parent: LocalDefId, node_id: ast::NodeId, data: DefPathData, - expn_id: ExpnId, - span: Span, ) -> LocalDefId { assert!( self.opt_local_def_id(node_id).is_none(), @@ -478,7 +482,7 @@ fn create_def( self.definitions.def_key(self.local_def_id(node_id)), ); - let def_id = self.definitions.create_def(parent, data, expn_id, span); + let def_id = self.definitions.create_def(parent, data); // 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 @@ -998,13 +1002,7 @@ fn lower_assoc_ty_constraint( let parent_def_id = self.current_hir_id_owner; let impl_trait_node_id = self.next_node_id(); - self.create_def( - parent_def_id, - impl_trait_node_id, - DefPathData::ImplTrait, - ExpnId::root(), - constraint.span, - ); + self.create_def(parent_def_id, impl_trait_node_id, DefPathData::ImplTrait); self.with_dyn_type_scope(false, |this| { let node_id = this.next_node_id(); @@ -1110,13 +1108,7 @@ fn lower_generic_arg( let node_id = self.next_node_id(); // Add a definition for the in-band const def. - self.create_def( - parent_def_id, - node_id, - DefPathData::AnonConst, - ExpnId::root(), - ty.span, - ); + self.create_def(parent_def_id, node_id, DefPathData::AnonConst); let span = self.lower_span(ty.span); let path_expr = Expr { @@ -1624,13 +1616,7 @@ fn lower_async_fn_ret_ty( let inner_node_id = self.next_node_id(); // Add a definition for the in scope lifetime def. - self.create_def( - opaque_ty_def_id, - inner_node_id, - DefPathData::LifetimeNs(name), - ExpnId::root(), - span.with_parent(None), - ); + self.create_def(opaque_ty_def_id, inner_node_id, DefPathData::LifetimeNs(name)); let (p_name, inner_res) = match outer_res { // Input lifetime like `'a`: @@ -1824,8 +1810,6 @@ fn new_named_lifetime_with_res( captured_lifetimes.parent_def_id, p_id, DefPathData::LifetimeNs(p_name.ident().name), - ExpnId::root(), - span.with_parent(None), ); v.insert((span, p_id, p_name, res)); @@ -1850,8 +1834,6 @@ fn new_named_lifetime_with_res( captured_lifetimes.parent_def_id, p_id, DefPathData::LifetimeNs(kw::UnderscoreLifetime), - ExpnId::root(), - span.with_parent(None), ); v.insert((span, p_id, ParamName::Fresh, res)); @@ -1873,8 +1855,6 @@ fn new_named_lifetime_with_res( captured_lifetimes.parent_def_id, p_id, DefPathData::LifetimeNs(kw::UnderscoreLifetime), - ExpnId::root(), - span.with_parent(None), ); captured_lifetimes .captures diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 5c32dd372dd..5f8801cc4e2 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -11,9 +11,7 @@ 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::{kw, sym, Symbol}; -use rustc_span::Span; use std::fmt::{self, Write}; use std::hash::Hash; @@ -101,11 +99,6 @@ pub struct Definitions { table: DefPathTable, next_disambiguator: FxHashMap<(LocalDefId, DefPathData), u32>, - /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. - expansions_that_defined: FxHashMap, - - def_id_to_span: IndexVec, - /// The [StableCrateId] of the local crate. stable_crate_id: StableCrateId, } @@ -323,7 +316,7 @@ pub fn def_path(&self, id: LocalDefId) -> DefPath { } /// Adds a root definition (no parent) and a few other reserved definitions. - pub fn new(stable_crate_id: StableCrateId, crate_span: Span) -> Definitions { + pub fn new(stable_crate_id: StableCrateId) -> Definitions { let key = DefKey { parent: None, disambiguated_data: DisambiguatedDefPathData { @@ -340,30 +333,12 @@ pub fn new(stable_crate_id: StableCrateId, crate_span: Span) -> Definitions { let root = LocalDefId { local_def_index: table.allocate(key, def_path_hash) }; assert_eq!(root.local_def_index, CRATE_DEF_INDEX); - let mut def_id_to_span = IndexVec::new(); - // A relative span's parent must be an absolute span. - debug_assert_eq!(crate_span.data_untracked().parent, None); - let _root = def_id_to_span.push(crate_span); - debug_assert_eq!(_root, root); - - Definitions { - table, - next_disambiguator: Default::default(), - expansions_that_defined: Default::default(), - def_id_to_span, - stable_crate_id, - } + Definitions { table, next_disambiguator: Default::default(), stable_crate_id } } /// Adds a definition with a parent definition. - pub fn create_def( - &mut self, - parent: LocalDefId, - data: DefPathData, - expn_id: ExpnId, - span: Span, - ) -> LocalDefId { - debug!("create_def(parent={:?}, data={:?}, expn_id={:?})", parent, data, expn_id); + pub fn create_def(&mut self, parent: LocalDefId, data: DefPathData) -> LocalDefId { + debug!("create_def(parent={:?}, data={:?})", parent, data); // The root node must be created with `create_root_def()`. assert!(data != DefPathData::CrateRoot); @@ -386,28 +361,7 @@ pub fn create_def( debug!("create_def: after disambiguation, key = {:?}", key); // Create the definition. - let def_id = LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) }; - - if expn_id != ExpnId::root() { - self.expansions_that_defined.insert(def_id, expn_id); - } - - // A relative span's parent must be an absolute span. - debug_assert_eq!(span.data_untracked().parent, None); - let _id = self.def_id_to_span.push(span); - debug_assert_eq!(_id, def_id); - - def_id - } - - pub fn expansion_that_defined(&self, id: LocalDefId) -> ExpnId { - self.expansions_that_defined.get(&id).copied().unwrap_or_else(ExpnId::root) - } - - /// Retrieves the span of the given `DefId` if `DefId` is in the local crate. - #[inline] - pub fn def_span(&self, def_id: LocalDefId) -> Span { - self.def_id_to_span[def_id] + LocalDefId { local_def_index: self.table.allocate(key, def_path_hash) } } pub fn iter_local_def_id(&self) -> impl Iterator + '_ { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 73aa23ce2b2..9d77d640a15 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1078,6 +1078,8 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { let upstream_crates = upstream_crates(tcx); + let resolutions = tcx.resolutions(()); + // We hash the final, remapped names of all local source files so we // don't have to include the path prefix remapping commandline args. // If we included the full mapping in the SVH, we could only have @@ -1107,7 +1109,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { .filter_map(|(def_id, info)| { let _ = info.as_owner()?; let def_path_hash = definitions.def_path_hash(def_id); - let span = definitions.def_span(def_id); + let span = resolutions.source_span[def_id]; debug_assert_eq!(span.parent(), None); Some((def_path_hash, span)) }) @@ -1118,7 +1120,6 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { tcx.sess.opts.dep_tracking_hash(true).hash_stable(&mut hcx, &mut stable_hasher); tcx.sess.local_stable_crate_id().hash_stable(&mut hcx, &mut stable_hasher); // Hash visibility information since it does not appear in HIR. - let resolutions = tcx.resolutions(()); resolutions.visibilities.hash_stable(&mut hcx, &mut stable_hasher); resolutions.has_pub_restricted.hash_stable(&mut hcx, &mut stable_hasher); diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 8068e6dff95..09b142e0c41 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -13,7 +13,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::*; use rustc_query_system::ich::StableHashingContext; -use rustc_span::DUMMY_SP; +use rustc_span::{ExpnId, DUMMY_SP}; /// Top-level HIR node for current owner. This only contains the node for which /// `HirId::local_id == 0`, and excludes bodies. @@ -117,7 +117,8 @@ pub fn provide(providers: &mut Providers) { }; providers.hir_attrs = |tcx, id| tcx.hir_crate(()).owners[id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs); - providers.source_span = |tcx, def_id| tcx.definitions_untracked().def_span(def_id); + providers.source_span = + |tcx, def_id| tcx.resolutions(()).source_span.get(def_id).copied().unwrap_or(DUMMY_SP); providers.def_span = |tcx, def_id| { let def_id = def_id.expect_local(); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); @@ -147,7 +148,7 @@ pub fn provide(providers: &mut Providers) { providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; providers.expn_that_defined = |tcx, id| { let id = id.expect_local(); - tcx.definitions_untracked().expansion_that_defined(id) + tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root()) }; providers.in_scope_traits_map = |tcx, id| tcx.hir_crate(()).owners[id].as_owner().map(|owner_info| &owner_info.trait_map); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index ce075805aef..e0b4eced075 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -31,7 +31,6 @@ /// This span is meant for dep-tracking rather than diagnostics. It should not be used outside /// of rustc_middle::hir::source_map. query source_span(key: LocalDefId) -> Span { - eval_always desc { "get the source span" } } @@ -272,8 +271,6 @@ } query expn_that_defined(key: DefId) -> rustc_span::ExpnId { - // This query reads from untracked data in definitions. - eval_always desc { |tcx| "expansion that defined `{}`", tcx.def_path_str(key) } separate_provide_extern } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 5d020f429c0..4464a0211fc 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -180,6 +180,7 @@ fn intern_ty( sess: &Session, definitions: &rustc_hir::definitions::Definitions, cstore: &CrateStoreDyn, + source_span: &IndexVec, ) -> Ty<'tcx> { Ty(Interned::new_unchecked( self.type_ @@ -194,7 +195,12 @@ fn intern_ty( Fingerprint::ZERO } else { let mut hasher = StableHasher::new(); - let mut hcx = StableHashingContext::ignore_spans(sess, definitions, cstore); + let mut hcx = StableHashingContext::ignore_spans( + sess, + definitions, + cstore, + source_span, + ); kind.hash_stable(&mut hcx, &mut hasher); hasher.finish() }; @@ -934,8 +940,9 @@ fn new( sess: &Session, definitions: &rustc_hir::definitions::Definitions, cstore: &CrateStoreDyn, + source_span: &IndexVec, ) -> CommonTypes<'tcx> { - let mk = |ty| interners.intern_ty(ty, sess, definitions, cstore); + let mk = |ty| interners.intern_ty(ty, sess, definitions, cstore, source_span); CommonTypes { unit: mk(Tuple(List::empty())), @@ -1235,7 +1242,14 @@ pub fn create_global_ctxt( s.fatal(&err); }); let interners = CtxtInterners::new(arena); - let common_types = CommonTypes::new(&interners, s, &definitions, &*cstore); + let common_types = CommonTypes::new( + &interners, + s, + &definitions, + &*cstore, + // This is only used to create a stable hashing context. + &untracked_resolutions.source_span, + ); let common_lifetimes = CommonLifetimes::new(&interners); let common_consts = CommonConsts::new(&interners, &common_types); @@ -1452,14 +1466,31 @@ pub fn definitions_untracked(self) -> &'tcx hir::definitions::Definitions { &self.definitions } + /// Note that this is *untracked* and should only be used within the query + /// system if the result is otherwise tracked through queries + #[inline] + pub fn source_span_untracked(self, def_id: LocalDefId) -> Span { + self.untracked_resolutions.source_span.get(def_id).copied().unwrap_or(DUMMY_SP) + } + #[inline(always)] pub fn create_stable_hashing_context(self) -> StableHashingContext<'tcx> { - StableHashingContext::new(self.sess, &self.definitions, &*self.cstore) + StableHashingContext::new( + self.sess, + &self.definitions, + &*self.cstore, + &self.untracked_resolutions.source_span, + ) } #[inline(always)] pub fn create_no_span_stable_hashing_context(self) -> StableHashingContext<'tcx> { - StableHashingContext::ignore_spans(self.sess, &self.definitions, &*self.cstore) + StableHashingContext::ignore_spans( + self.sess, + &self.definitions, + &*self.cstore, + &self.untracked_resolutions.source_span, + ) } pub fn serialize_query_result_cache(self, encoder: FileEncoder) -> FileEncodeResult { @@ -2250,7 +2281,14 @@ pub fn reuse_or_mk_region(self, r: Region<'tcx>, kind: RegionKind) -> Region<'tc #[allow(rustc::usage_of_ty_tykind)] #[inline] pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> { - self.interners.intern_ty(st, self.sess, &self.definitions, &*self.cstore) + self.interners.intern_ty( + st, + self.sess, + &self.definitions, + &*self.cstore, + // This is only used to create a stable hashing context. + &self.untracked_resolutions.source_span, + ) } #[inline] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index e0cb0cb9709..26b45c5c644 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -43,7 +43,7 @@ use rustc_query_system::ich::StableHashingContext; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::Span; +use rustc_span::{ExpnId, Span}; use rustc_target::abi::{Align, VariantIdx}; pub use subst::*; pub use vtable::*; @@ -138,6 +138,10 @@ pub struct ResolverOutputs { pub visibilities: FxHashMap, /// This field is used to decide whether we should make `PRIVATE_IN_PUBLIC` a hard error. pub has_pub_restricted: bool, + /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. + pub expn_that_defined: FxHashMap, + /// Reference span for definitions. + pub source_span: IndexVec, pub access_levels: AccessLevels, pub extern_crate_map: FxHashMap, pub maybe_unused_trait_imports: FxIndexSet, diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index c2c876f7f1a..166fd1d272d 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -689,8 +689,7 @@ fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self { let dlo = u32::decode(decoder); let dto = u32::decode(decoder); - let enclosing = - decoder.tcx.definitions_untracked().def_span(parent.unwrap()).data_untracked(); + let enclosing = decoder.tcx.source_span_untracked(parent.unwrap()).data_untracked(); let span = Span::new( enclosing.lo + BytePos::from_u32(dlo), enclosing.lo + BytePos::from_u32(dto), @@ -887,7 +886,7 @@ fn encode(&self, s: &mut CacheEncoder<'a, 'tcx, E>) { } if let Some(parent) = span_data.parent { - let enclosing = s.tcx.definitions_untracked().def_span(parent).data_untracked(); + let enclosing = s.tcx.source_span(parent).data_untracked(); if enclosing.contains(span_data) { TAG_RELATIVE_SPAN.encode(s); (span_data.lo - enclosing.lo).to_u32().encode(s); diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index 03ef8578eb7..d120742ffe3 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -7,6 +7,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::definitions::{DefPathHash, Definitions}; +use rustc_index::vec::IndexVec; use rustc_session::cstore::CrateStore; use rustc_session::Session; use rustc_span::source_map::SourceMap; @@ -26,6 +27,7 @@ fn compute_ignored_attr_names() -> FxHashSet { pub struct StableHashingContext<'a> { definitions: &'a Definitions, cstore: &'a dyn CrateStore, + source_span: &'a IndexVec, // The value of `-Z incremental-ignore-spans`. // This field should only be used by `debug_opts_incremental_ignore_span` incremental_ignore_spans: bool, @@ -56,6 +58,7 @@ fn new_with_or_without_spans( sess: &'a Session, definitions: &'a Definitions, cstore: &'a dyn CrateStore, + source_span: &'a IndexVec, always_ignore_spans: bool, ) -> Self { let hash_spans_initial = @@ -65,6 +68,7 @@ fn new_with_or_without_spans( body_resolver: BodyResolver::Forbidden, definitions, cstore, + source_span, incremental_ignore_spans: sess.opts.debugging_opts.incremental_ignore_spans, caching_source_map: None, raw_source_map: sess.source_map(), @@ -77,11 +81,13 @@ pub fn new( sess: &'a Session, definitions: &'a Definitions, cstore: &'a dyn CrateStore, + source_span: &'a IndexVec, ) -> Self { Self::new_with_or_without_spans( sess, definitions, cstore, + source_span, /*always_ignore_spans=*/ false, ) } @@ -91,9 +97,10 @@ pub fn ignore_spans( sess: &'a Session, definitions: &'a Definitions, cstore: &'a dyn CrateStore, + source_span: &'a IndexVec, ) -> Self { let always_ignore_spans = true; - Self::new_with_or_without_spans(sess, definitions, cstore, always_ignore_spans) + Self::new_with_or_without_spans(sess, definitions, cstore, source_span, always_ignore_spans) } /// Allow hashing @@ -198,7 +205,7 @@ fn def_path_hash(&self, def_id: DefId) -> DefPathHash { #[inline] fn def_span(&self, def_id: LocalDefId) -> Span { - self.definitions.def_span(def_id) + self.source_span[def_id] } #[inline] diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 3b70b90c871..e7c8886f054 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -10,8 +10,9 @@ use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PerNS}; -use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::PrimTy; +use rustc_index::vec::IndexVec; use rustc_middle::bug; use rustc_middle::ty::DefIdTree; use rustc_session::lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE; @@ -130,8 +131,8 @@ fn report_with_use_injections(&mut self, krate: &Crate) { }; if !candidates.is_empty() { show_candidates( - &self.definitions, - self.session, + &self.session, + &self.source_span, &mut err, span, &candidates, @@ -693,8 +694,8 @@ pub(crate) fn into_struct_error( err.span_help(span, &help_msg); } show_candidates( - &self.definitions, - self.session, + &self.session, + &self.source_span, &mut err, Some(span), &import_suggestions, @@ -1474,8 +1475,8 @@ pub(crate) fn unresolved_macro_suggestions( let import_suggestions = self.lookup_import_candidates(ident, Namespace::MacroNS, parent_scope, is_expected); show_candidates( - &self.definitions, - self.session, + &self.session, + &self.source_span, err, None, &import_suggestions, @@ -2444,8 +2445,8 @@ enum IsPattern { /// entities with that name in all crates. This method allows outputting the /// results of this search in a programmer-friendly way fn show_candidates( - definitions: &rustc_hir::definitions::Definitions, session: &Session, + source_span: &IndexVec, err: &mut Diagnostic, // This is `None` if all placement locations are inside expansions use_placement_span: Option, @@ -2555,7 +2556,7 @@ fn show_candidates( ); if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) { - let span = definitions.def_span(local_def_id); + let span = source_span[local_def_id]; let span = session.source_map().guess_head_span(span); let mut multi_span = MultiSpan::from_span(span); multi_span.push_span_label(span, "not accessible".to_string()); @@ -2584,7 +2585,7 @@ fn show_candidates( let mut spans = Vec::new(); for (name, _, def_id, _) in &inaccessible_path_strings { if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) { - let span = definitions.def_span(local_def_id); + let span = source_span[local_def_id]; let span = session.source_map().guess_head_span(span); spans.push((name, span)); } else { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index eb58f17fc7e..b04a5ef8161 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -872,6 +872,10 @@ pub struct Resolver<'a> { session: &'a Session, definitions: Definitions, + /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. + expn_that_defined: FxHashMap, + /// Reference span for definitions. + source_span: IndexVec, graph_root: Module<'a>, @@ -1146,7 +1150,17 @@ fn create_def( self.definitions.def_key(self.node_id_to_def_id[&node_id]), ); - let def_id = self.definitions.create_def(parent, data, expn_id, span); + let def_id = self.definitions.create_def(parent, data); + + // Create the definition. + if expn_id != ExpnId::root() { + self.expn_that_defined.insert(def_id, expn_id); + } + + // A relative span's parent must be an absolute span. + debug_assert_eq!(span.data_untracked().parent, None); + let _id = self.source_span.push(span); + debug_assert_eq!(_id, 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 @@ -1196,7 +1210,7 @@ pub fn new( &mut FxHashMap::default(), ); - let definitions = Definitions::new(session.local_stable_crate_id(), krate.spans.inner_span); + let definitions = Definitions::new(session.local_stable_crate_id()); let mut visibilities = FxHashMap::default(); visibilities.insert(CRATE_DEF_ID, ty::Visibility::Public); @@ -1209,6 +1223,10 @@ pub fn new( let mut invocation_parents = FxHashMap::default(); invocation_parents.insert(LocalExpnId::ROOT, (CRATE_DEF_ID, ImplTraitContext::Existential)); + let mut source_span = IndexVec::default(); + let _id = source_span.push(krate.spans.inner_span); + debug_assert_eq!(_id, CRATE_DEF_ID); + let mut extern_prelude: FxHashMap> = session .opts .externs @@ -1233,6 +1251,8 @@ pub fn new( session, definitions, + expn_that_defined: Default::default(), + source_span, // The outermost module has def ID 0; this is not reflected in the // AST. @@ -1376,6 +1396,8 @@ pub fn into_outputs(self) -> (Definitions, Box, ResolverOutputs) let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); let definitions = self.definitions; let cstore = Box::new(self.crate_loader.into_cstore()); + let source_span = self.source_span; + let expn_that_defined = self.expn_that_defined; let visibilities = self.visibilities; let has_pub_restricted = self.has_pub_restricted; let extern_crate_map = self.extern_crate_map; @@ -1387,6 +1409,8 @@ pub fn into_outputs(self) -> (Definitions, Box, ResolverOutputs) let confused_type_with_std_module = self.confused_type_with_std_module; let access_levels = self.access_levels; let resolutions = ResolverOutputs { + source_span, + expn_that_defined, visibilities, has_pub_restricted, access_levels, @@ -1426,6 +1450,8 @@ pub fn clone_outputs(&self) -> (Definitions, Box, ResolverOutputs let definitions = self.definitions.clone(); let cstore = Box::new(self.cstore().clone()); let resolutions = ResolverOutputs { + source_span: self.source_span.clone(), + expn_that_defined: self.expn_that_defined.clone(), visibilities: self.visibilities.clone(), has_pub_restricted: self.has_pub_restricted, extern_crate_map: self.extern_crate_map.clone(), @@ -1461,7 +1487,12 @@ pub fn clone_outputs(&self) -> (Definitions, Box, ResolverOutputs } fn create_stable_hashing_context(&self) -> StableHashingContext<'_> { - StableHashingContext::new(self.session, &self.definitions, self.crate_loader.cstore()) + StableHashingContext::new( + self.session, + &self.definitions, + self.crate_loader.cstore(), + &self.source_span, + ) } pub fn cstore(&self) -> &CStore { @@ -1892,7 +1923,7 @@ pub fn macro_rules_scope(&self, def_id: LocalDefId) -> (MacroRulesScopeRef<'a>, /// Retrieves the span of the given `DefId` if `DefId` is in the local crate. #[inline] pub fn opt_span(&self, def_id: DefId) -> Option { - def_id.as_local().map(|def_id| self.definitions.def_span(def_id)) + def_id.as_local().map(|def_id| self.source_span[def_id]) } /// Checks if an expression refers to a function marked with