Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix macro hygiene regression #34374

Merged
merged 5 commits into from
Jun 23, 2016
Merged

Fix macro hygiene regression #34374

merged 5 commits into from
Jun 23, 2016

Conversation

jseyfried
Copy link
Contributor

@jseyfried jseyfried commented Jun 20, 2016

The regression was caused by #32923, which is currently in beta.

The following is an example of regressed code:

fn main() {
    let x = 0;
    macro_rules! foo { () => {
        println!("{}", x); // prints `0` on stable and after this PR, prints `1` on beta and nightly
    } }

    let x = 1;
    foo!();
}

For code to regress, the following is necessary (but not sufficient):

  • There must be a local variable before a macro in a block, and the macro must use the variable.
  • There must be a second local variable with the same name after the macro.
  • The macro must be invoked in a statement position after the second local variable.

For example, if the let x = 0; from the breaking example were commented out, it would (correctly) not compile on beta/nightly. If the semicolon were removed from foo!();, it would (correctly) print 0 on beta and nightly.

r? @nrc

@jseyfried jseyfried force-pushed the fix_hygiene_bug branch 2 times, most recently from 02e7d44 to b65bc42 Compare June 20, 2016 11:23
@jseyfried jseyfried changed the title Fix hygiene bug involving macro-expanded macros Fix macro hygiene regression Jun 20, 2016
@jseyfried
Copy link
Contributor Author

jseyfried commented Jun 20, 2016

This is the simplest way I could come up with to fix the regression while keeping #32922, #31856, #10681, and #26223 fixed. While I am very confident that it is correct, we (understandably) might not want to backport this big of a change to beta.

In that case, I think we should consider reverting #32923 on beta to avoid regressing hygiene on stable. However, the hygiene bug that #32923 fixes, i.e.:

fn main() {
    let x = 0;
    macro_rules! foo { () => {
        let x = 1;
        println!("{}", x); // prints `0` on stable, should print `1`
    } }
    m!();
}

is arguably worse than the regression.

@nrc nrc added beta-nominated Nominated for backporting to the compiler in the beta channel. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 21, 2016
@nrc
Copy link
Member

nrc commented Jun 21, 2016

What is the motivation for removing all the unit tests? r+ other than that.

@jseyfried
Copy link
Contributor Author

jseyfried commented Jun 21, 2016

@nrc
Some tests were testing functionality that I removed (resolve_table_hashing_test, test_marksof, xorpush_test) and some tests were using functionality that I removed (e.g. run_renaming_test was using mtwt::marksof). Also, the signatures and semantics of many of the functions changed, so I'd have to almost completely rewrite the tests. Finally, the tests are difficult to read, and I haven't entirely grokked what they are doing.

I believe it would be a better use of time to write more run-pass and compile-fail tests like the ones I added in the last two commits. Perhaps if we had written more of these tests earlier, we would have caught #32922 and this regression sooner. Also, these tests will be far more useful for checking future changes to our hygiene implementation.

That being said, I can try to rewrite the unit tests if you think it's worth it.

@jseyfried
Copy link
Contributor Author

jseyfried commented Jun 22, 2016

Also, I'm working on dramatically simplifying the hygiene algorithm (without changing semantics) to make it feasible to expand macros in an arbitrary order (needed for macro modularization). I discovered this regression while testing my implementation. Most of the unit tests are not relevant to the simplified implementation.

EDIT: Finished the hygiene simplification, see PR #34570.

@jseyfried
Copy link
Contributor Author

I added some more hygiene tests. r? @nrc

@nrc
Copy link
Member

nrc commented Jun 23, 2016

@bors: r+

@bors
Copy link
Contributor

bors commented Jun 23, 2016

📌 Commit eef8485 has been approved by nrc

@bors
Copy link
Contributor

bors commented Jun 23, 2016

⌛ Testing commit eef8485 with merge 4960f2f...

bors added a commit that referenced this pull request Jun 23, 2016
Fix macro hygiene regression

The regression was caused by #32923, which is currently in beta.

The following is an example of regressed code:
```rust
fn main() {
    let x = 0;
    macro_rules! foo { () => {
        println!("{}", x); // prints `0` on stable and after this PR, prints `1` on beta and nightly
    } }

    let x = 1;
    foo!();
}
```

For code to regress, the following is necessary (but not sufficient):
 - There must be a local variable before a macro in a block, and the macro must use the variable.
 - There must be a second local variable with the same name after the macro.
 - The macro must be invoked in a statement position after the second local variable.

For example, if the `let x = 0;` from the breaking example were commented out, it would (correctly) not compile on beta/nightly. If the semicolon were removed from `foo!();`, it would (correctly) print `0` on beta and nightly.

r? @nrc
@bors bors merged commit eef8485 into rust-lang:master Jun 23, 2016
@alexcrichton
Copy link
Member

cc @rust-lang/compiler

Thoughts on backporting? We hope to produce a new beta soon and would love to include this.

@nrc
Copy link
Member

nrc commented Jul 1, 2016

somewhat ambiguous about backporting. I think the patch is right, but it is pretty big for a backport, so I'd want to see it properly motivated, i.e., the regression is causing trouble, it's not just a technicality. If that is the case, then happy to backport.

@alexcrichton
Copy link
Member

@jseyfried do you know if this was causing trouble in the wild?

@alexcrichton
Copy link
Member

Note that we plan on building the stable 1.10 release tomorrow, so this is unlikely at this point to make a backport. If it's critical to include, though, we can push schedules back and make it work!

@jseyfried jseyfried deleted the fix_hygiene_bug branch July 3, 2016 18:54
@jseyfried
Copy link
Contributor Author

@alexcrichton No, as far as we know this has no impact in the wild, definitely not critical to include.

I still think it would be better to include it, but it's not a big deal -- not worth pushing back the release.

@alexcrichton
Copy link
Member

Ok, thanks for the update @jseyfried! In that case I'm going to remove the beta-nominated tag from this, but again if anything comes up we can make it work.

@alexcrichton alexcrichton removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label Jul 4, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants