-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #54605 - petrochenkov:mambig, r=alexcrichton
resolve: Disambiguate a subset of conflicts "macro_rules" vs "macro name in module" Currently if macro name may refer to both a `macro_rules` macro definition and a macro defined/imported into module we conservatively report an ambiguity error. Unfortunately, these errors became a source of regressions when macro modularization was enabled - see issue #54472. This PR disambiguates such conflicts in favor of `macro_rules` if both the `macro_rules` item and in-module macro name are defined in the same normal (named) module and `macro_rules` is closer in scope to the point of use (see the tests for examples). This is a subset of more general approach described in #54472 (comment). The subset is enough to fix all the regressions from #54472, but it can be extended to apply to all "macro_rules" vs "macro name in module" conflicts in the future. To give an analogy, this is equivalent to scoping rules for `let` variables and items defined in blocks (`macro_rules` behaves like "`let` at module level" in general). ```rust { // beginning of the block use xxx::m; // (1) // Starting from the beginning of the block and until here m!() refers to (1) macro_rules! m { ... } // (2) // Starting from here and until the end of the block m!() refers to (2) } // end of the block ``` More complex examples with `use` and `macro_rules` from different modules still report ambiguity errors, even if equivalent examples with `let` are legal. Fixes #54472 (stable-to-beta regression)
- Loading branch information
Showing
7 changed files
with
130 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,7 +45,7 @@ mod m3 { | |
mod m4 { | ||
macro_rules! m { () => {} } | ||
use two_macros::m; | ||
m!(); //~ ERROR ambiguous | ||
m!(); | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Some non-controversial subset of ambiguities "modern macro name" vs "macro_rules" | ||
// is disambiguated to mitigate regressions from macro modularization. | ||
// Scoping for `macro_rules` behaves like scoping for `let` at module level, in general. | ||
|
||
#![feature(decl_macro)] | ||
|
||
fn same_unnamed_mod() { | ||
macro m() { 0 } | ||
|
||
macro_rules! m { () => (()) } | ||
|
||
m!() // OK | ||
} | ||
|
||
fn nested_unnamed_mod() { | ||
macro m() { 0 } | ||
|
||
{ | ||
macro_rules! m { () => (()) } | ||
|
||
m!() // OK | ||
} | ||
} | ||
|
||
fn nested_unnamed_mod_fail() { | ||
macro_rules! m { () => (()) } | ||
|
||
{ | ||
macro m() { 0 } | ||
|
||
m!() //~ ERROR `m` is ambiguous | ||
} | ||
} | ||
|
||
fn nexted_named_mod_fail() { | ||
macro m() { 0 } | ||
|
||
#[macro_use] | ||
mod inner { | ||
macro_rules! m { () => (()) } | ||
} | ||
|
||
m!() //~ ERROR `m` is ambiguous | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
error[E0659]: `m` is ambiguous | ||
--> $DIR/ambiguity-legacy-vs-modern.rs:31:9 | ||
| | ||
LL | m!() //~ ERROR `m` is ambiguous | ||
| ^ ambiguous name | ||
| | ||
note: `m` could refer to the name defined here | ||
--> $DIR/ambiguity-legacy-vs-modern.rs:26:5 | ||
| | ||
LL | macro_rules! m { () => (()) } | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
note: `m` could also refer to the name defined here | ||
--> $DIR/ambiguity-legacy-vs-modern.rs:29:9 | ||
| | ||
LL | macro m() { 0 } | ||
| ^^^^^^^^^^^^^^^ | ||
|
||
error[E0659]: `m` is ambiguous | ||
--> $DIR/ambiguity-legacy-vs-modern.rs:43:5 | ||
| | ||
LL | m!() //~ ERROR `m` is ambiguous | ||
| ^ ambiguous name | ||
| | ||
note: `m` could refer to the name defined here | ||
--> $DIR/ambiguity-legacy-vs-modern.rs:40:9 | ||
| | ||
LL | macro_rules! m { () => (()) } | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
note: `m` could also refer to the name defined here | ||
--> $DIR/ambiguity-legacy-vs-modern.rs:36:5 | ||
| | ||
LL | macro m() { 0 } | ||
| ^^^^^^^^^^^^^^^ | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0659`. |