macros: Make metavariables hygienic#35453
Conversation
|
@bors: r+ |
|
📌 Commit cdbfe9f has been approved by |
|
⌛ Testing commit cdbfe9f with merge 26f17ba... |
|
💔 Test failed - auto-win-gnu-64-opt |
|
LLVM didn't build? |
|
@bors: retry
|
|
⌛ Testing commit cdbfe9f with merge 70bb60c... |
|
💔 Test failed - auto-win-gnu-32-opt-rustbuild |
|
|
📌 Commit b62ff25 has been approved by |
|
📌 Commit b62ff25 has been approved by |
b62ff25 to
95b68aa
Compare
|
📌 Commit 95b68aa has been approved by |
|
So... this is a syntax-breaking change if there is test fallout (sorry). |
|
cc @Manishearth |
|
@durka Good point. |
|
I think so. @dtolnay whatsay? |
|
We're gettign a pile of PRs that will break aster (and only aster) right now though. So it might be good to do a rollup. OTOH there's a bunch of diagnostics work coming up which I'd like to include. |
|
This PR does not affect quasi/aster. For the others - I have time in the next two weeks to deal with fallout so this would be a good time. Thanks for the heads up. |
|
Cool. @GuillaumeGomez could you get all libsyntax refactors necessary for diagnostics in now? |
|
@bors r=nrc |
|
📌 Commit 95b68aa has been approved by |
|
⌛ Testing commit 95b68aa with merge f6ba0ad... |
|
@bors: retry force clean
|
macros: Make metavariables hygienic
This PR makes metavariables hygienic. For example, consider:
```rust
macro_rules! foo {
($x:tt) => { // Suppose that this token tree argument is always a metavariable.
macro_rules! bar { ($x:expr, $y:expr) => { ($x, $y) } }
}
}
fn main() {
foo!($z); // This currently compiles.
foo!($y); // This is an error today but compiles after this PR.
}
```
Today, the `macro_rules! bar { ... }` definition is only valid when the metavariable passed to `foo` is not `$y` (since it unhygienically conflicts with the `$y` in the definition of `bar`) or `$x` (c.f. #35450).
After this PR, the definition of `bar` is always valid (and `bar!(a, b)` always expands to `(a, b)` as expected).
This can break code that was allowed in #34925 (landed two weeks ago). For example,
```rust
macro_rules! outer {
($t:tt) => {
macro_rules! inner { ($i:item) => { $t } }
}
}
outer!($i); // This `$i` should not interact with the `$i` in the definition of `inner!`.
inner!(fn main() {}); // After this PR, this is an error ("unknown macro variable `i`").
```
Due to the severe limitations on nested `macro_rules!` before #34925, this is not a breaking change for stable/beta.
Fixes #35450.
r? @nrc
This PR makes metavariables hygienic. For example, consider:
Today, the
macro_rules! bar { ... }definition is only valid when the metavariable passed tofoois not$y(since it unhygienically conflicts with the$yin the definition ofbar) or$x(c.f. #35450).After this PR, the definition of
baris always valid (andbar!(a, b)always expands to(a, b)as expected).This can break code that was allowed in #34925 (landed two weeks ago). For example,
Due to the severe limitations on nested
macro_rules!before #34925, this is not a breaking change for stable/beta.Fixes #35450.
r? @nrc