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

macros: improve 1.0/2.0 interaction #46551

Merged

Conversation

jseyfried
Copy link
Contributor

@jseyfried jseyfried commented Dec 7, 2017

This PR supports using unhygienic macros from hygienic macros without breaking the latter's hygiene.

// crate A:
#[macro_export]
macro_rules! m1 { () => {
    f(); // unhygienic: this macro needs `f` in its environment
    fn g() {} // (1) unhygienic: `g` is usable outside the macro definition
} }

// crate B:
#![feature(decl_macro)]
extern crate A;
use A::m1;

macro m2() {
    fn f() {} // (2)
    m1!(); // After this PR, `f()` in the expansion resolves to (2), not (3)
    g(); // After this PR, this resolves to `fn g() {}` from the above expansion.
         // Today, it is a resolution error.
}

fn test() {
    fn f() {} // (3)
    m2!(); // Today, `m2!()` can see (3) even though it should be hygienic.
    fn g() {} // Today, this conflicts with `fn g() {}` from the expansion, even though it should be hygienic.
}

Once this PR lands, you can make an existing unhygienic macro hygienic by wrapping it in a hygienic macro. There is an example of this in the tests.

r? @nrc

@@ -95,7 +95,7 @@ impl FromStr for TokenStream {
// notify the expansion info that it is unhygienic
let mark = Mark::fresh(mark);
mark.set_expn_info(expn_info);
let span = call_site.with_ctxt(call_site.ctxt().apply_mark(mark));
let span = call_site.with_ctxt(SyntaxContext::empty().apply_mark(mark));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kennytm kennytm added the S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. label Dec 7, 2017
@kennytm kennytm added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. labels Dec 13, 2017
@kennytm
Copy link
Member

kennytm commented Dec 13, 2017

Both #46550 and #46419 have been merged.

@jseyfried jseyfried force-pushed the improve_legacy_modern_macro_interaction branch 2 times, most recently from fb04829 to d6a8566 Compare December 13, 2017 20:42
@jseyfried jseyfried force-pushed the improve_legacy_modern_macro_interaction branch from d6a8566 to b766fa8 Compare December 13, 2017 21:33
@kennytm
Copy link
Member

kennytm commented Dec 20, 2017

Review ping for you @nrc!

@alexcrichton
Copy link
Member

ping @nrc, this may be ready for a look now!

@kennytm
Copy link
Member

kennytm commented Jan 10, 2018

Review ping for you @nrc!

@nrc
Copy link
Member

nrc commented Jan 12, 2018

@bors: r+

@bors
Copy link
Contributor

bors commented Jan 12, 2018

📌 Commit b766fa8 has been approved by nrc

@bors
Copy link
Contributor

bors commented Jan 12, 2018

⌛ Testing commit b766fa8 with merge 0b90e4e...

bors added a commit that referenced this pull request Jan 12, 2018
…ion, r=nrc

macros: improve 1.0/2.0 interaction

This PR supports using unhygienic macros from hygienic macros without breaking the latter's hygiene.
```rust
// crate A:
#[macro_export]
macro_rules! m1 { () => {
    f(); // unhygienic: this macro needs `f` in its environment
    fn g() {} // (1) unhygienic: `g` is usable outside the macro definition
} }

// crate B:
#![feature(decl_macro)]
extern crate A;
use A::m1;

macro m2() {
    fn f() {} // (2)
    m1!(); // After this PR, `f()` in the expansion resolves to (2), not (3)
    g(); // After this PR, this resolves to `fn g() {}` from the above expansion.
         // Today, it is a resolution error.
}

fn test() {
    fn f() {} // (3)
    m2!(); // Today, `m2!()` can see (3) even though it should be hygienic.
    fn g() {} // Today, this conflicts with `fn g() {}` from the expansion, even though it should be hygienic.
}
```

Once this PR lands, you can make an existing unhygienic macro hygienic by wrapping it in a hygienic macro. There is an [example](b766fa8) of this in the tests.

r? @nrc
@bors
Copy link
Contributor

bors commented Jan 12, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: nrc
Pushing 0b90e4e to master...

@bors bors merged commit b766fa8 into rust-lang:master Jan 12, 2018
@jseyfried jseyfried deleted the improve_legacy_modern_macro_interaction branch March 23, 2018 21:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants