diff options
| author | Aaron Hill <aa1ronham@gmail.com> | 2021-07-14 18:24:12 -0500 |
|---|---|---|
| committer | Aaron Hill <aa1ronham@gmail.com> | 2021-07-17 23:03:56 -0500 |
| commit | ddd544856ecd181ee02490d12f723be549d3ecb3 (patch) | |
| tree | 36bec16c3a8132f356fdb4713a63aac33e0471a9 /compiler/rustc_resolve | |
| parent | eb0b95b55a0b38d91e834dd30902b67627ed2eb0 (diff) | |
| download | rust-ddd544856ecd181ee02490d12f723be549d3ecb3.tar.gz rust-ddd544856ecd181ee02490d12f723be549d3ecb3.zip | |
Compute a better `lint_node_id` during expansion
When we need to emit a lint at a macro invocation, we currently use the `NodeId` of its parent definition (e.g. the enclosing function). This means that any `#[allow]` / `#[deny]` attributes placed 'closer' to the macro (e.g. on an enclosing block or statement) will have no effect. This commit computes a better `lint_node_id` in `InvocationCollector`. When we visit/flat_map an AST node, we assign it a `NodeId` (earlier than we normally would), and store than `NodeId` in current `ExpansionData`. When we collect a macro invocation, the current `lint_node_id` gets cloned along with our `ExpansionData`, allowing it to be used if we need to emit a lint later on. This improves the handling of `#[allow]` / `#[deny]` for `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` and some `asm!`-related lints. The 'legacy derive helpers' lint retains its current behavior (I've inlined the now-removed `lint_node_id` function), since there isn't an `ExpansionData` readily available.
Diffstat (limited to 'compiler/rustc_resolve')
| -rw-r--r-- | compiler/rustc_resolve/src/macros.rs | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 86f271fdece..b2a8aa0cecc 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -281,7 +281,7 @@ impl<'a> ResolverExpand for Resolver<'a> { // Derives are not included when `invocations` are collected, so we have to add them here. let parent_scope = &ParentScope { derives, ..parent_scope }; let supports_macro_expansion = invoc.fragment_kind.supports_macro_expansion(); - let node_id = self.lint_node_id(eager_expansion_root); + let node_id = invoc.expansion_data.lint_node_id; let (ext, res) = self.smart_resolve_macro_path( path, kind, @@ -348,14 +348,6 @@ impl<'a> ResolverExpand for Resolver<'a> { } } - fn lint_node_id(&self, expn_id: LocalExpnId) -> NodeId { - // FIXME - make this more precise. This currently returns the NodeId of the - // nearest closing item - we should try to return the closest parent of the ExpnId - self.invocation_parents - .get(&expn_id) - .map_or(ast::CRATE_NODE_ID, |id| self.def_id_to_node_id[id.0]) - } - fn has_derive_copy(&self, expn_id: LocalExpnId) -> bool { self.containers_deriving_copy.contains(&expn_id) } @@ -1105,9 +1097,13 @@ impl<'a> Resolver<'a> { let seg = Segment::from_ident(ident); check_consistency(self, &[seg], ident.span, kind, initial_res, res); if res == Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat) { + let node_id = self + .invocation_parents + .get(&parent_scope.expansion) + .map_or(ast::CRATE_NODE_ID, |id| self.def_id_to_node_id[id.0]); self.lint_buffer.buffer_lint_with_diagnostic( LEGACY_DERIVE_HELPERS, - self.lint_node_id(parent_scope.expansion), + node_id, ident.span, "derive helper attribute is used before it is introduced", BuiltinLintDiagnostics::LegacyDeriveHelpers(binding.span), |
