diff options
| author | bors <bors@rust-lang.org> | 2021-09-11 23:35:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-09-11 23:35:28 +0000 |
| commit | 547d9374d26f203ab963b3ffe1ed36bd70f16633 (patch) | |
| tree | f104eb31a70bdab19db7cf39db1fa19ec129fe07 /compiler/rustc_resolve | |
| parent | 8c2b6ea37d7719a0370bd404030eef9702c1752c (diff) | |
| parent | 7842b80478ae92e2b7956f61bb14b76d17f57140 (diff) | |
Auto merge of #84373 - cjgillot:resolve-span, r=michaelwoerister,petrochenkov
Encode spans relative to the enclosing item The aim of this PR is to avoid recomputing queries when code is moved without modification. MCP at https://github.com/rust-lang/compiler-team/issues/443 This is achieved by : 1. storing the HIR owner LocalDefId information inside the span; 2. encoding and decoding spans relative to the enclosing item in the incremental on-disk cache; 3. marking a dependency to the `source_span(LocalDefId)` query when we translate a span from the short (`Span`) representation to its explicit (`SpanData`) representation. Since all client code uses `Span`, step 3 ensures that all manipulations of span byte positions actually create the dependency edge between the caller and the `source_span(LocalDefId)`. This query return the actual absolute span of the parent item. As a consequence, any source code motion that changes the absolute byte position of a node will either: - modify the distance to the parent's beginning, so change the relative span's hash; - dirty `source_span`, and trigger the incremental recomputation of all code that depends on the span's absolute byte position. With this scheme, I believe the dependency tracking to be accurate. For the moment, the spans are marked during lowering. I'd rather do this during def-collection, but the AST MutVisitor is not practical enough just yet. The only difference is that we attach macro-expanded spans to their expansion point instead of the macro itself.
Diffstat (limited to 'compiler/rustc_resolve')
| -rw-r--r-- | compiler/rustc_resolve/src/def_collector.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/macros.rs | 4 |
4 files changed, 25 insertions, 11 deletions
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 6f4f1bdaea1..5879cb1daa5 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -32,7 +32,13 @@ 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(parent_def, node_id, data, self.expansion.to_expn_id(), span) + self.resolver.create_def( + parent_def, + node_id, + data, + self.expansion.to_expn_id(), + span.with_parent(None), + ) } fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: LocalDefId, f: F) { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index b2c0c787465..a11d7a69c54 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -768,6 +768,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { args[1].span.lo(), args.last().unwrap().span.hi(), call_span.ctxt(), + None, )) } else { None diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 392d618995a..7fb1e92440b 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1012,8 +1012,6 @@ pub struct Resolver<'a> { next_node_id: NodeId, - def_id_to_span: IndexVec<LocalDefId, Span>, - node_id_to_def_id: FxHashMap<ast::NodeId, LocalDefId>, def_id_to_node_id: IndexVec<LocalDefId, ast::NodeId>, @@ -1116,6 +1114,11 @@ impl ResolverAstLowering for Resolver<'_> { } } + #[inline] + fn def_span(&self, id: LocalDefId) -> Span { + self.definitions.def_span(id) + } + fn item_generics_num_lifetimes(&self, def_id: DefId) -> usize { if let Some(def_id) = def_id.as_local() { self.item_generics_num_lifetimes[&def_id] @@ -1197,9 +1200,7 @@ impl ResolverAstLowering for Resolver<'_> { 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); + let def_id = self.definitions.create_def(parent, data, expn_id, next_disambiguator, span); // 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 @@ -1226,6 +1227,11 @@ impl<'a, 'b> rustc_span::HashStableContext for ExpandHasher<'a, 'b> { } #[inline] + fn def_span(&self, id: LocalDefId) -> Span { + self.resolver.def_span(id) + } + + #[inline] fn def_path_hash(&self, def_id: DefId) -> DefPathHash { self.resolver.def_path_hash(def_id) } @@ -1269,14 +1275,12 @@ impl<'a> Resolver<'a> { let mut module_map = FxHashMap::default(); module_map.insert(root_local_def_id, graph_root); - let definitions = Definitions::new(session.local_stable_crate_id()); + let definitions = Definitions::new(session.local_stable_crate_id(), krate.span); let root = definitions.get_root_def(); let mut visibilities = FxHashMap::default(); visibilities.insert(root_local_def_id, ty::Visibility::Public); - 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(); @@ -1393,7 +1397,6 @@ impl<'a> Resolver<'a> { .collect(), 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(), @@ -3360,7 +3363,7 @@ impl<'a> Resolver<'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<Span> { - if let Some(def_id) = def_id.as_local() { Some(self.def_id_to_span[def_id]) } else { None } + def_id.as_local().map(|def_id| self.definitions.def_span(def_id)) } /// Checks if an expression refers to a function marked with diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 6dc3aa0888a..4dbac47c3cc 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -180,6 +180,10 @@ impl<'a> ResolverExpand for Resolver<'a> { self.next_node_id() } + fn invocation_parent(&self, id: LocalExpnId) -> LocalDefId { + self.invocation_parents[&id].0 + } + fn resolve_dollar_crates(&mut self) { hygiene::update_dollar_crate_names(|ctxt| { let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt)); |
