Skip to content

Commit

Permalink
Auto merge of rust-lang#79294 - petrochenkov:determ, r=varkor
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
bors committed Nov 24, 2020
2 parents 238994f + 27af650 commit 6331023
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 97 deletions.
29 changes: 20 additions & 9 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

Expand Down Expand Up @@ -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),
Expand All @@ -1309,15 +1313,15 @@ 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);
}
}

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;
}

Expand All @@ -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 {
self.visit_invoc(item.id);
match ctxt {
AssocCtxt::Trait => {
self.visit_invoc_in_module(item.id);
}
AssocCtxt::Impl => {
self.visit_invoc(item.id);
}
}
return;
}

Expand Down Expand Up @@ -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;
}

Expand Down
24 changes: 12 additions & 12 deletions src/test/ui/conditional-compilation/cfg-generic-params.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ 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;
| ^^^^^^^
LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {}
| ^^^^^^^

error: cannot find attribute `unknown` in this scope
--> $DIR/cfg-generic-params.rs:30:40
--> $DIR/cfg-generic-params.rs:22:29
|
LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy;
| ^^^^^^^
LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {}
| ^^^^^^^

error: cannot find attribute `unknown` in this scope
--> $DIR/cfg-generic-params.rs:26:34
Expand All @@ -35,16 +35,16 @@ LL | type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn();
| ^^^^^^^

error: cannot find attribute `unknown` in this scope
--> $DIR/cfg-generic-params.rs:22:29
--> $DIR/cfg-generic-params.rs:30:40
|
LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {}
| ^^^^^^^
LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy;
| ^^^^^^^

error: cannot find attribute `unknown` in this scope
--> $DIR/cfg-generic-params.rs:19:29
--> $DIR/cfg-generic-params.rs:34:43
|
LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {}
| ^^^^^^^
LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
| ^^^^^^^

error: aborting due to 8 previous errors

128 changes: 64 additions & 64 deletions src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr
Original file line number Diff line number Diff line change
@@ -1,104 +1,104 @@
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_meth` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:44:15
error: cannot find attribute `lt_enum` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:9:13
|
LL | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
| ^^^^^^^
LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B }
| ^^^^^^^

error: cannot find attribute `ty_fn` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:40:11
error: cannot find attribute `ty_enum` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:11:13
|
LL | fn f_ty<#[ty_fn] O>(_: O) { }
| ^^^^^
LL | enum EnTy<#[ty_enum] J> { A(J), B }
| ^^^^^^^

error: cannot find attribute `lt_fn` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:38:11
error: cannot find attribute `lt_trait` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:14:14
|
LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
| ^^^^^
LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
| ^^^^^^^^

error: cannot find attribute `ty_impl_for` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:33:8
error: cannot find attribute `ty_trait` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:16:14
|
LL | impl<#[ty_impl_for] N> TrTy<N> for StTy<N> {
| ^^^^^^^^^^^
LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); }
| ^^^^^^^^

error: cannot find attribute `lt_impl_for` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:29:8
error: cannot find attribute `lt_type` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:19:13
|
LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
| ^^^^^^^^^^^
LL | type TyLt<#[lt_type] 'd> = &'d u32;
| ^^^^^^^

error: cannot find attribute `ty_inherent` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:26:8
error: cannot find attribute `ty_type` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:21:13
|
LL | impl<#[ty_inherent] M> StTy<M> { }
| ^^^^^^^^^^^
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_type` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:21:13
error: cannot find attribute `ty_inherent` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:26:8
|
LL | type TyTy<#[ty_type] L> = (L, );
| ^^^^^^^
LL | impl<#[ty_inherent] M> StTy<M> { }
| ^^^^^^^^^^^

error: cannot find attribute `lt_type` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:19:13
error: cannot find attribute `lt_impl_for` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:29:8
|
LL | type TyLt<#[lt_type] 'd> = &'d u32;
| ^^^^^^^
LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
| ^^^^^^^^^^^

error: cannot find attribute `ty_trait` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:16:14
error: cannot find attribute `ty_impl_for` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:33:8
|
LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); }
| ^^^^^^^^
LL | impl<#[ty_impl_for] N> TrTy<N> for StTy<N> {
| ^^^^^^^^^^^

error: cannot find attribute `lt_trait` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:14:14
error: cannot find attribute `lt_fn` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:38:11
|
LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
| ^^^^^^^^
LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
| ^^^^^

error: cannot find attribute `ty_enum` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:11:13
error: cannot find attribute `ty_fn` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:40:11
|
LL | enum EnTy<#[ty_enum] J> { A(J), B }
| ^^^^^^^
LL | fn f_ty<#[ty_fn] O>(_: O) { }
| ^^^^^

error: cannot find attribute `lt_enum` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:9:13
error: cannot find attribute `lt_meth` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:44:15
|
LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B }
| ^^^^^^^
LL | fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
| ^^^^^^^

error: cannot find attribute `ty_struct` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:6:15
error: cannot find attribute `ty_meth` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:46:15
|
LL | struct StTy<#[ty_struct] I>(I);
| ^^^^^^^^^
LL | fn m_ty<#[ty_meth] P>(_: P) { }
| ^^^^^^^

error: cannot find attribute `lt_struct` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:4:15
error: cannot find attribute `lt_hof` in this scope
--> $DIR/feature-gate-custom_attribute2.rs:51:21
|
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

12 changes: 6 additions & 6 deletions src/test/ui/issues/issue-40845.stderr
Original file line number Diff line number Diff line change
@@ -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

4 changes: 2 additions & 2 deletions src/test/ui/parser/default-unmatched-assoc.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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!();
| ^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ LL | mac2! { does_not_exist!() }
= 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
--> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:22:13
|
LL | mac1! { does_not_exist!() }
LL | mac2! { does_not_exist!() }
| ^^^^^^^^^^^^^^

error: cannot find macro `does_not_exist` in this scope
--> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:22:13
--> $DIR/issue-65122-mac-invoc-in-mut-patterns.rs:20:13
|
LL | mac2! { does_not_exist!() }
LL | mac1! { does_not_exist!() }
| ^^^^^^^^^^^^^^

error: aborting due to 5 previous errors
Expand Down
7 changes: 7 additions & 0 deletions src/test/ui/resolve/macro-determinacy-non-module.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// check-pass

use std as line;

const C: u32 = line!();

fn main() {}

0 comments on commit 6331023

Please sign in to comment.