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

Stabilize Span::mixed_site #68716

Merged
merged 1 commit into from
Apr 27, 2020
Merged

Stabilize Span::mixed_site #68716

merged 1 commit into from
Apr 27, 2020

Conversation

petrochenkov
Copy link
Contributor

@petrochenkov petrochenkov commented Jan 31, 2020

Closes #65049.
cc #54727 (comment)

Pre-requisite for #68717 ("Stabilize fn-like proc macros in expression, pattern and statement positions").

Stabilization report: #68716 (comment).

@rust-highfive
Copy link
Collaborator

r? @nikomatsakis

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 31, 2020
@jonas-schievink jonas-schievink added the relnotes Marks issues that should be documented in the release notes of the next release. label Jan 31, 2020
@jonas-schievink jonas-schievink added this to the 1.43 milestone Jan 31, 2020
@jonas-schievink jonas-schievink added A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) T-lang Relevant to the language team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Jan 31, 2020
@jhpratt

This comment has been minimized.

@jonas-schievink jonas-schievink added the needs-fcp This change is insta-stable, so needs a completed FCP to proceed. label Jan 31, 2020
@petrochenkov

This comment has been minimized.

@petrochenkov
Copy link
Contributor Author

Stabilization report

This PR stabilizes a proc macro API Span::mixed_site() exposing macro_rules hygiene to proc macro authors.

Tracking issue: #65049
Version target: 1.43

Technical specification

Procedural macro producing tokens with Span::mixed_site() spans should be equivalent to a macro_rules macro producing the same tokens.
Identifiers with this span will resolve at the macro's definition site for local variables, labels and $crate, and resolve at the call site for everything else.

Motivation

Proc macros do not have direct access to our oldest and most stable hygiene kind - macro_rules hygiene.

To emulate it macro authors have to go through two steps - first generate a temporary macro_rules item, then generate a macro call to that item. Popular crates like proc_macro_hack use this trick to generate hygienic identifiers from proc macros.

I'd say that these workarounds with nested macro definitions have more chances to hit some corner cases in our hygiene system, in which we don't have full confidence.
So, let's provide a direct access to macro_rules hygiene instead.
This access is provided with a method Span::mixed_site, which is similar to existing Span::call_site (stable, fully unhygienic) and Span::def_site (unstable, fully hygienic).

This API addition opens the way to stabilizing proc macros in expression, pattern and statement positions (#68717), for which use of call-site hygiene or workarounds with temporary items would be quite unfortunate.
macro_rules expanded in all these positions, on the other hand, are stable since 1.0 and widely used.
So, we are suggesting to stabilize such use of procedural macros and give a way to proc macro authors to make these macros reasonably hygienic with Span::mixed_site.

Tests

ui/proc-macro/mixed-site-span.rs makes sure that the API works.
Otherwise, all tests for macro_rules test the underlying mechanism.

History

The implementation (#64690) was merged about 4 months ago.

@petrochenkov
Copy link
Contributor Author

r? @dtolnay

@rust-highfive rust-highfive assigned dtolnay and unassigned nikomatsakis Feb 1, 2020
@Centril
Copy link
Contributor

Centril commented Feb 2, 2020

This API addition opens the way to stabilizing proc macros in expression, pattern and statement positions (#68717), for which use of call-site hygiene or workarounds with temporary items would be quite unfortunate.

One thing I'm wondering about here is the documentation ("how do we teach this") aspect and making it easy to "do the right thing" wrt. hygiene in expr/pat/stmt contexts. Hygiene is, in my experience, one of the less well known parts of the language and so it seems like this could be easy to get wrong without good teaching material. In the implementation PR, @dtolnay noted (#64690 (comment)) that:

I will try to test whether changing the default span of quote! from call_site to mixed_site on sufficiently new compilers can possibly break anything that's currently stable. The alternative would be adding a macro like quote_expr! that is shorthand for quote_spanned!(Span::mixed_site()=>...).

I'm wondering if more thought has been put into this. @CAD97 did note in #64690 (comment) that changing to mixed_site could trivially break some crates using quote!, which is now a 1.0.X crate, so it seems like the most practical path would be quote_expr! { ... } (although that name is sub-optimal for patterns & statements).

@petrochenkov
Copy link
Contributor Author

@Centril
I'm not sure this is our problem.
AFAIK, most user-facing APIs are provided by third-party crates, proc_macro only provides primitives.

The recommendation on using Span::mixed_site is #64690 (comment) - use it everywhere unless you specifically want unhygienic local variables, labels or $crate, which is a rare case.

I don't understand why the @CAD97's example would be broken, it doesn't seem to involve local variables.

@Centril
Copy link
Contributor

Centril commented Feb 2, 2020

The teams should, in my view, still be interested in the wider ecosystem effects with respect to #68717 and not just the narrow technical aspect of mixed_site. We should make sure we're not inadvertently laying traps for users.

Specifically, I'm somewhat concerned that the recommendation won't be heeded by many due to the relative ergonomics of quote!(...) vs quote_spanned!(Span::mixed_site()=> ...). So having some sort of plan for how to address that would be good. If quote! can change to mixed_site then the issue is resolved, but if not, it might involve adding a second macro to quote (e.g. q!(...)) and deprecating the other macro. (This is primarily directed at @dtolnay.)

@dtolnay
Copy link
Member

dtolnay commented Feb 2, 2020

I would be interested in a crater run that changes proc_macro::Span::call_site() to call mixed_site(), as a way to mimic what would happen from replacing quote's default. I agree with #68716 (comment) that I don't understand why the example given in the other PR would break.

  • If nothing breaks, that's great.
  • If the only things that break are things using unstable proc_macro_hygiene, we can evaluate but I am open to breaking those.
  • If more complicated, this may be a good time to introduce impl Default for Span which produces call_site or mixed_site depending on whether we are in the expansion of an attribute/item macro vs expr/pat/stmt macro.

@Centril
Copy link
Contributor

Centril commented Feb 2, 2020

A crater run sounds like a great idea. 👍

(I'm skeptical of Default for Span but we can have that discussion when necessary.)

@petrochenkov
Copy link
Contributor Author

I would be interested in a crater run that changes proc_macro::Span::call_site() to call mixed_site(), as a way to mimic what would happen from replacing quote's default.

#68766 is the PR doing that.

@dtolnay dtolnay added S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. labels Feb 3, 2020
@dtolnay
Copy link
Member

dtolnay commented Feb 7, 2020

#68766 (comment) has the experiment results.

I haven't looked into the regressions too closely, but it seems a large variety of derive macros and attribute macros no longer work. That suggests to me mixed_site may not be a reasonable default and that it should be reserved as a power tool. But I intend to take a closer look at what particular patterns exhibit different behavior (and I could use all of your help with this). It is interesting that serde_derive seems completely fine using mixed_site everywhere.

@petrochenkov
Copy link
Contributor Author

petrochenkov commented Feb 7, 2020

I'm also interested in finding out the root regressions and patterns that they represent.
It's possible that a few root regressions in some popular crate cause the high total number of regressed crates.

@petrochenkov
Copy link
Contributor Author

Blocked on #69041 (which should land in the same or earlier release than this PR).

@petrochenkov petrochenkov added S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. and removed S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). labels Apr 19, 2020
@Dylan-DPC-zz Dylan-DPC-zz modified the milestones: 1.44, 1.45 Apr 21, 2020
@petrochenkov petrochenkov 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 Apr 25, 2020
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Apr 25, 2020
proc_macro: Stabilize `Span::resolved_at` and `Span::located_at`

Introduced in rust-lang#47149.
Part of rust-lang#54725.

Motivation: rust-lang#68716 (comment).
Identifiers in proc macros may want to inherit span locations for diagnostics from one tokens (e.g. some tokens from the macro input), but resolve those identifiers from some different location (e.g. from the macro's definition site).
This becomes especially important when multiple resolution locations become available with stabilization of [`Span::mixed_site`](rust-lang#68716).

Why I think this is the right API for setting span's location and hygiene - rust-lang#69041 (comment).

r? @dtolnay
@petrochenkov
Copy link
Contributor Author

ping @dtolnay, this is unblocked and needs an official r+.

@dtolnay
Copy link
Member

dtolnay commented Apr 26, 2020

@bors r+

@bors
Copy link
Contributor

bors commented Apr 26, 2020

📌 Commit f5223a3 has been approved by dtolnay

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 26, 2020
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 27, 2020
Rollup of 6 pull requests

Successful merges:

 - rust-lang#68716 (Stabilize `Span::mixed_site`)
 - rust-lang#71263 (Remove unused abs_path method from rustc_span::source_map::FileLoader)
 - rust-lang#71409 (Point at the return type on `.into()` failure caused by `?`)
 - rust-lang#71419 (add message for resolution failure because wrong namespace)
 - rust-lang#71438 (Tweak some suggestions in `rustc_resolve`)
 - rust-lang#71589 (remove Unique::from for shared pointer types)

Failed merges:

r? @ghost
@bors bors merged commit 9d00252 into rust-lang:master Apr 27, 2020
kevinmehall added a commit to kevinmehall/proc-macro2 that referenced this pull request May 18, 2020
bors added a commit to rust-lang-ci/rust that referenced this pull request May 19, 2020
Stabilize fn-like proc macros in expression, pattern and statement positions

I.e. all the positions in which stable `macro_rules` macros are supported.

Depends on rust-lang#68716 ("Stabilize `Span::mixed_site`").

cc rust-lang#54727
cc rust-lang#54727 (comment)

Stabilization report: rust-lang#68717 (comment).
flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request May 19, 2020
Stabilize fn-like proc macros in expression, pattern and statement positions

I.e. all the positions in which stable `macro_rules` macros are supported.

Depends on rust-lang/rust#68716 ("Stabilize `Span::mixed_site`").

cc rust-lang/rust#54727
cc rust-lang/rust#54727 (comment)

Stabilization report: rust-lang/rust#68717 (comment).
kevinmehall added a commit to kevinmehall/proc-macro2 that referenced this pull request May 19, 2020
phansch pushed a commit to phansch/rust-clippy that referenced this pull request May 24, 2020
Stabilize fn-like proc macros in expression, pattern and statement positions

I.e. all the positions in which stable `macro_rules` macros are supported.

Depends on rust-lang/rust#68716 ("Stabilize `Span::mixed_site`").

cc rust-lang/rust#54727
cc rust-lang/rust#54727 (comment)

Stabilization report: rust-lang/rust#68717 (comment).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-lang Relevant to the language team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tracking issue for Span::mixed_site