Auto merge of #79294 - petrochenkov:determ, r=varkor
resolve: Do not put macros into `module.unexpanded_invocations` unless necessary Macro invocations in modules <sup>(*)</sup> need to be tracked because they can produce named items when expanded. We cannot give definite answer to queries like "does this module declare name `n`?" until all macro calls in that module are expanded. Previously we marked too many macros as potentially producing named items. E.g. in this example ```rust mod m { const C: u32 = line!(); } ``` `line!()` cannot emit any items into module `m`, but it was still marked. This PR fixes that and marks macro calls as "unexpanded in module" only if they can actually emit named items into that module. Diagnostics in UI test outputs have different order now because this change affects macro expansion order. <sup>*</sup> Any containers for named items are called modules in resolve (that includes blocks, traits and enums in addition to `mod` items).
This commit is contained in:
commit
6331023708
7 changed files with 125 additions and 107 deletions
|
@ -1155,14 +1155,18 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
|||
false
|
||||
}
|
||||
|
||||
fn visit_invoc(&mut self, id: NodeId) -> MacroRulesScopeRef<'a> {
|
||||
fn visit_invoc(&mut self, id: NodeId) -> ExpnId {
|
||||
let invoc_id = id.placeholder_to_expn_id();
|
||||
|
||||
self.parent_scope.module.unexpanded_invocations.borrow_mut().insert(invoc_id);
|
||||
|
||||
let old_parent_scope = self.r.invocation_parent_scopes.insert(invoc_id, self.parent_scope);
|
||||
assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation");
|
||||
invoc_id
|
||||
}
|
||||
|
||||
/// Visit invocation in context in which it can emit a named item (possibly `macro_rules`)
|
||||
/// directly into its parent scope's module.
|
||||
fn visit_invoc_in_module(&mut self, id: NodeId) -> MacroRulesScopeRef<'a> {
|
||||
let invoc_id = self.visit_invoc(id);
|
||||
self.parent_scope.module.unexpanded_invocations.borrow_mut().insert(invoc_id);
|
||||
self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Invocation(invoc_id))
|
||||
}
|
||||
|
||||
|
@ -1291,7 +1295,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
|
|||
return;
|
||||
}
|
||||
ItemKind::MacCall(..) => {
|
||||
self.parent_scope.macro_rules = self.visit_invoc(item.id);
|
||||
self.parent_scope.macro_rules = self.visit_invoc_in_module(item.id);
|
||||
return;
|
||||
}
|
||||
ItemKind::Mod(..) => self.contains_macro_use(&item.attrs),
|
||||
|
@ -1309,7 +1313,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
|
|||
|
||||
fn visit_stmt(&mut self, stmt: &'b ast::Stmt) {
|
||||
if let ast::StmtKind::MacCall(..) = stmt.kind {
|
||||
self.parent_scope.macro_rules = self.visit_invoc(stmt.id);
|
||||
self.parent_scope.macro_rules = self.visit_invoc_in_module(stmt.id);
|
||||
} else {
|
||||
visit::walk_stmt(self, stmt);
|
||||
}
|
||||
|
@ -1317,7 +1321,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
|
|||
|
||||
fn visit_foreign_item(&mut self, foreign_item: &'b ForeignItem) {
|
||||
if let ForeignItemKind::MacCall(_) = foreign_item.kind {
|
||||
self.visit_invoc(foreign_item.id);
|
||||
self.visit_invoc_in_module(foreign_item.id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1336,7 +1340,14 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
|
|||
|
||||
fn visit_assoc_item(&mut self, item: &'b AssocItem, ctxt: AssocCtxt) {
|
||||
if let AssocItemKind::MacCall(_) = item.kind {
|
||||
match ctxt {
|
||||
AssocCtxt::Trait => {
|
||||
self.visit_invoc_in_module(item.id);
|
||||
}
|
||||
AssocCtxt::Impl => {
|
||||
self.visit_invoc(item.id);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1460,7 +1471,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
|
|||
// type and value namespaces.
|
||||
fn visit_variant(&mut self, variant: &'b ast::Variant) {
|
||||
if variant.is_placeholder {
|
||||
self.visit_invoc(variant.id);
|
||||
self.visit_invoc_in_module(variant.id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,21 +17,9 @@ LL | struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy;
|
|||
| ^
|
||||
|
||||
error: cannot find attribute `unknown` in this scope
|
||||
--> $DIR/cfg-generic-params.rs:34:43
|
||||
--> $DIR/cfg-generic-params.rs:19:29
|
||||
|
|
||||
LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `unknown` in this scope
|
||||
--> $DIR/cfg-generic-params.rs:30:40
|
||||
|
|
||||
LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy;
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `unknown` in this scope
|
||||
--> $DIR/cfg-generic-params.rs:26:34
|
||||
|
|
||||
LL | type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn();
|
||||
LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {}
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `unknown` in this scope
|
||||
|
@ -41,9 +29,21 @@ LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {}
|
|||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `unknown` in this scope
|
||||
--> $DIR/cfg-generic-params.rs:19:29
|
||||
--> $DIR/cfg-generic-params.rs:26:34
|
||||
|
|
||||
LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {}
|
||||
LL | type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn();
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `unknown` in this scope
|
||||
--> $DIR/cfg-generic-params.rs:30:40
|
||||
|
|
||||
LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy;
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `unknown` in this scope
|
||||
--> $DIR/cfg-generic-params.rs:34:43
|
||||
|
|
||||
LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
|
|
@ -1,43 +1,55 @@
|
|||
error: cannot find attribute `lt_hof` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:51:21
|
||||
error: cannot find attribute `lt_struct` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:4:15
|
||||
|
|
||||
LL | where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
|
||||
| ^^^^^^
|
||||
LL | struct StLt<#[lt_struct] 'a>(&'a u32);
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: cannot find attribute `ty_meth` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:46:15
|
||||
error: cannot find attribute `ty_struct` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:6:15
|
||||
|
|
||||
LL | fn m_ty<#[ty_meth] P>(_: P) { }
|
||||
LL | struct StTy<#[ty_struct] I>(I);
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: cannot find attribute `lt_enum` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:9:13
|
||||
|
|
||||
LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B }
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `lt_meth` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:44:15
|
||||
error: cannot find attribute `ty_enum` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:11:13
|
||||
|
|
||||
LL | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
|
||||
LL | enum EnTy<#[ty_enum] J> { A(J), B }
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `ty_fn` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:40:11
|
||||
error: cannot find attribute `lt_trait` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:14:14
|
||||
|
|
||||
LL | fn f_ty<#[ty_fn] O>(_: O) { }
|
||||
| ^^^^^
|
||||
LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
|
||||
| ^^^^^^^^
|
||||
|
||||
error: cannot find attribute `lt_fn` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:38:11
|
||||
error: cannot find attribute `ty_trait` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:16:14
|
||||
|
|
||||
LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
|
||||
| ^^^^^
|
||||
LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); }
|
||||
| ^^^^^^^^
|
||||
|
||||
error: cannot find attribute `ty_impl_for` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:33:8
|
||||
error: cannot find attribute `lt_type` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:19:13
|
||||
|
|
||||
LL | impl<#[ty_impl_for] N> TrTy<N> for StTy<N> {
|
||||
| ^^^^^^^^^^^
|
||||
LL | type TyLt<#[lt_type] 'd> = &'d u32;
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `lt_impl_for` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:29:8
|
||||
error: cannot find attribute `ty_type` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:21:13
|
||||
|
|
||||
LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
|
||||
LL | type TyTy<#[ty_type] L> = (L, );
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `lt_inherent` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:24:8
|
||||
|
|
||||
LL | impl<#[lt_inherent] 'e> StLt<'e> { }
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: cannot find attribute `ty_inherent` in this scope
|
||||
|
@ -46,59 +58,47 @@ error: cannot find attribute `ty_inherent` in this scope
|
|||
LL | impl<#[ty_inherent] M> StTy<M> { }
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: cannot find attribute `lt_inherent` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:24:8
|
||||
error: cannot find attribute `lt_impl_for` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:29:8
|
||||
|
|
||||
LL | impl<#[lt_inherent] 'e> StLt<'e> { }
|
||||
LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: cannot find attribute `ty_type` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:21:13
|
||||
error: cannot find attribute `ty_impl_for` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:33:8
|
||||
|
|
||||
LL | type TyTy<#[ty_type] L> = (L, );
|
||||
LL | impl<#[ty_impl_for] N> TrTy<N> for StTy<N> {
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: cannot find attribute `lt_fn` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:38:11
|
||||
|
|
||||
LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
|
||||
| ^^^^^
|
||||
|
||||
error: cannot find attribute `ty_fn` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:40:11
|
||||
|
|
||||
LL | fn f_ty<#[ty_fn] O>(_: O) { }
|
||||
| ^^^^^
|
||||
|
||||
error: cannot find attribute `lt_meth` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:44:15
|
||||
|
|
||||
LL | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `lt_type` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:19:13
|
||||
error: cannot find attribute `ty_meth` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:46:15
|
||||
|
|
||||
LL | type TyLt<#[lt_type] 'd> = &'d u32;
|
||||
LL | fn m_ty<#[ty_meth] P>(_: P) { }
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `ty_trait` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:16:14
|
||||
error: cannot find attribute `lt_hof` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:51:21
|
||||
|
|
||||
LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); }
|
||||
| ^^^^^^^^
|
||||
|
||||
error: cannot find attribute `lt_trait` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:14:14
|
||||
|
|
||||
LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
|
||||
| ^^^^^^^^
|
||||
|
||||
error: cannot find attribute `ty_enum` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:11:13
|
||||
|
|
||||
LL | enum EnTy<#[ty_enum] J> { A(J), B }
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `lt_enum` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:9:13
|
||||
|
|
||||
LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B }
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find attribute `ty_struct` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:6:15
|
||||
|
|
||||
LL | struct StTy<#[ty_struct] I>(I);
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: cannot find attribute `lt_struct` in this scope
|
||||
--> $DIR/feature-gate-custom_attribute2.rs:4:15
|
||||
|
|
||||
LL | struct StLt<#[lt_struct] 'a>(&'a u32);
|
||||
| ^^^^^^^^^
|
||||
LL | where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to 17 previous errors
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
error: cannot find macro `m` in this scope
|
||||
--> $DIR/issue-40845.rs:4:10
|
||||
|
|
||||
LL | impl S { m!(); }
|
||||
| ^
|
||||
|
||||
error: cannot find macro `m` in this scope
|
||||
--> $DIR/issue-40845.rs:1:11
|
||||
|
|
||||
LL | trait T { m!(); }
|
||||
| ^
|
||||
|
||||
error: cannot find macro `m` in this scope
|
||||
--> $DIR/issue-40845.rs:4:10
|
||||
|
|
||||
LL | impl S { m!(); }
|
||||
| ^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -39,13 +39,13 @@ LL | }
|
|||
| - item list ends here
|
||||
|
||||
error: cannot find macro `default` in this scope
|
||||
--> $DIR/default-unmatched-assoc.rs:12:5
|
||||
--> $DIR/default-unmatched-assoc.rs:4:5
|
||||
|
|
||||
LL | default!();
|
||||
| ^^^^^^^
|
||||
|
||||
error: cannot find macro `default` in this scope
|
||||
--> $DIR/default-unmatched-assoc.rs:4:5
|
||||
--> $DIR/default-unmatched-assoc.rs:12:5
|
||||
|
|
||||
LL | default!();
|
||||
| ^^^^^^^
|
||||
|
|
|
@ -33,17 +33,17 @@ LL | mac2! { does_not_exist!() }
|
|||
= note: `mut` may be followed by `variable` and `variable @ pattern`
|
||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: cannot find macro `does_not_exist` in this scope
|
||||
--> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:20:13
|
||||
|
|
||||
LL | mac1! { does_not_exist!() }
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: cannot find macro `does_not_exist` in this scope
|
||||
--> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:22:13
|
||||
|
|
||||
LL | mac2! { does_not_exist!() }
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: cannot find macro `does_not_exist` in this scope
|
||||
--> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:20:13
|
||||
|
|
||||
LL | mac1! { does_not_exist!() }
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
7
src/test/ui/resolve/macro-determinacy-non-module.rs
Normal file
7
src/test/ui/resolve/macro-determinacy-non-module.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
// check-pass
|
||||
|
||||
use std as line;
|
||||
|
||||
const C: u32 = line!();
|
||||
|
||||
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue