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

proc_macro: Stabilize Span::resolved_at and Span::located_at #69041

Merged
merged 2 commits into from
Apr 25, 2020

Conversation

petrochenkov
Copy link
Contributor

@petrochenkov petrochenkov commented Feb 10, 2020

Introduced in #47149.
Part of #54725.

Motivation: #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.

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

r? @dtolnay

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 10, 2020
@jonas-schievink jonas-schievink added A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) relnotes Marks issues that should be documented in the release notes of the next release. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Feb 10, 2020
@jonas-schievink jonas-schievink added this to the 1.43 milestone Feb 10, 2020
@dtolnay dtolnay added the needs-fcp This change is insta-stable, so needs a completed FCP to proceed. label Feb 10, 2020
@Centril Centril added the T-lang Relevant to the language team, which will review and decide on the PR/issue. label Feb 11, 2020
@petrochenkov petrochenkov changed the title proc_macro: Stabilize Span::resolve_at and Span::located_at proc_macro: Stabilize Span::resolved_at and Span::located_at Feb 11, 2020
@jhpratt
Copy link
Member

jhpratt commented Feb 12, 2020

@SergioBenitez & @jebrosen may be interested in this as well.

@jebrosen
Copy link
Contributor

Yes, I suspect rocket could leverage these APIs for the same reason given in #68716 (comment) (mainly, diagnostic reporting).

@petrochenkov
Copy link
Contributor Author

There are a few alternatives in terms of naming and the function signatures here.
I think the status quo hits a sweet spot between them.

The primary alternative is some API looking like,

impl Span {
	fn set_location(&mut self, location: ???);
	fn set_hygiene_context(&mut self, hygiene_context: ???);
}

, which has some issues.

  • We don't have stable types representing the location alone and the hygienic context alone.
    All our API is in terms of spans and it seems reasonable to keep the API surface minimal as it is now for both simplicity (less types less issues) and faster stabilization.
    This means the API will combine locations and hygiene from spans.

     impl Span {
     	fn set_location_from(&mut self, location: Span);
     	fn set_hygiene_context_from(&mut self, hygiene_context: Span);
     }
    
  • The setter interface is just inconvenient in practice. Built-in macros in the compiler use similar location and hygiene combining a lot, and they eventually evolved to a functional-style API returning a new span rather than modifying the old one for ergonomics.

     impl Span {
     	fn with_location_from(&self, location: Span) -> Span;
     	fn with_hygiene_context_from(&mut self, hygiene_context: Span) -> Span;
     }
    

This kind of promises that Span is cheaply copyable, but we already kind of promise it because Span is already Copy.

  • "Hygiene context" is too abstract, nobody knows what it means, the name should preferably tell what the user-visible consequences the choice of context has, and the primary consequence is where the identifier with that context is resolved from.

So, fn located_at and fn resolved_at are basically better worded alternatives of the previous variant.

let span = input_subspan.resolved_at(Span::def_site()); // Nice

@Centril Centril modified the milestones: 1.43, 1.44 Mar 10, 2020
@petrochenkov
Copy link
Contributor Author

ping @dtolnay, this is waiting on you.

@dtolnay
Copy link
Member

dtolnay commented Mar 15, 2020

@rust-lang/libs @rust-lang/lang: This PR stabilizes these two methods of proc_macro::Span:

impl Span {
    /// Creates a new span with the same line/column information as `self` but
    /// that resolves symbols as though it were at `other`.
    pub fn resolved_at(&self, other: Span) -> Span;

    /// Creates a new span with the same name resolution behavior as `self` but
    /// with the line/column information of `other`.
    pub fn located_at(&self, other: Span) -> Span;
}

These are for mixing and matching the two pieces of information held by Span, source location and hygiene (≈ name resolution) context.

We have experience with these methods in Serde, e.g. serde-rs/serde@6457331. To take a look at one of the diffs from that commit:

- quote!(try!(_serde::de::SeqAccess::next_element::<#field_ty>(&mut __seq)))
+ let span = Span::def_site().located_at(field.original.span());
+ let func = quote_spanned!(span=> _serde::de::SeqAccess::next_element::<#field_ty>);
+ quote!(try!(#func(&mut __seq)))

In this code:

  • Name resolution needs to happen at def_site, because the symbol _serde is defined as extern crate serde as _serde by the generated code and is not necessarily in scope at the call site, or if it is, it may refer to something different at the call site.
  • But if the relevant Deserialize trait impl is missing on #field_ty, we would really like for that error to appear pointing to the correct field inside the user's struct at the call site.

The green implementation uses Span::located_at to combine def_site's hygiene context with the caller's field's source location to get compilable code that produces good error messages.

@rfcbot fcp merge

@rfcbot
Copy link

rfcbot commented Mar 15, 2020

Team member @dtolnay has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Mar 15, 2020
@Centril Centril removed the needs-fcp This change is insta-stable, so needs a completed FCP to proceed. label Mar 15, 2020
@Centril
Copy link
Contributor

Centril commented Mar 15, 2020

Reviewed, but do we have relevant tests for these methods? (i.e. as exposed, and not via tests exercising the deeper internal mechanism)

@petrochenkov petrochenkov added S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 16, 2020
@Dylan-DPC-zz Dylan-DPC-zz added S-waiting-on-fcp Status: PR is in FCP and is awaiting for FCP to complete. and removed S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). labels Apr 3, 2020
@petrochenkov
Copy link
Contributor Author

Reviewed, but do we have relevant tests for these methods? (i.e. as exposed, and not via tests exercising the deeper internal mechanism)

No, we don't. I'll add a test.

@nikomatsakis
Copy link
Contributor

@rfcbot reviewed

My feelings here are similar to my comments from mixed_site. I am gratified to hear that serde has been using these APIs to get a good user experience.

@rfcbot rfcbot added the final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. label Apr 15, 2020
@petrochenkov
Copy link
Contributor Author

Test is added.

@HadrienG2 HadrienG2 mentioned this pull request Apr 20, 2020
11 tasks
@Dylan-DPC-zz Dylan-DPC-zz modified the milestones: 1.44, 1.45 Apr 21, 2020
@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Apr 25, 2020
@rfcbot
Copy link

rfcbot commented Apr 25, 2020

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

The RFC will be merged soon.

@petrochenkov petrochenkov added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-fcp Status: PR is in FCP and is awaiting for FCP to complete. labels Apr 25, 2020
@Amanieu
Copy link
Member

Amanieu commented Apr 25, 2020

@bors r+

@bors
Copy link
Contributor

bors commented Apr 25, 2020

📌 Commit 966a295 has been approved by Amanieu

@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 25, 2020
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 25, 2020
Rollup of 7 pull requests

Successful merges:

 - rust-lang#69041 (proc_macro: Stabilize `Span::resolved_at` and `Span::located_at`)
 - rust-lang#69813 (Implement BitOr and BitOrAssign for the NonZero integer types)
 - rust-lang#70712 (stabilize BTreeMap::remove_entry)
 - rust-lang#71168 (Deprecate `{Box,Rc,Arc}::into_raw_non_null`)
 - rust-lang#71544 (Replace filter_map().next() calls with find_map())
 - rust-lang#71545 (Fix comment in docstring example for Error::kind)
 - rust-lang#71548 (Add missing Send and Sync impls for linked list Cursor and CursorMut.)

Failed merges:

r? @ghost
@bors
Copy link
Contributor

bors commented Apr 25, 2020

⌛ Testing commit 966a295 with merge 0862458...

@bors bors merged commit 7b7c63c into rust-lang:master Apr 25, 2020
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Apr 26, 2020
proc_macro: Fix since attributes for new Span methods

Added in rust-lang#69041, took a while to merge so the since attributes went out of date.
@@ -352,14 +352,14 @@ impl Span {

/// Creates a new span with the same line/column information as `self` but
/// that resolves symbols as though it were at `other`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[stable(feature = "proc_macro_span_resolved_at", since = "1.43.0")]

Choose a reason for hiding this comment

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

So maybe I'm being stupid but since this was merged on the 25th April shouldn't this be since = "1.44.0" what with 1.43.0 being released on the 23rd April

Copy link
Contributor

Choose a reason for hiding this comment

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

With 1.43 released before this was merged, it's actually going to be stabilized in 1.45 (the GitHub milestone this PR is assigned to is also the one for 1.45). I've already opened #71574 to fix the attribute.

Choose a reason for hiding this comment

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

So I'm not crazy? Good to know :-)

kevinmehall added a commit to kevinmehall/proc-macro2 that referenced this pull request May 18, 2020
kevinmehall added a commit to kevinmehall/proc-macro2 that referenced this pull request May 19, 2020
On compilers prior to 1.45 where this is not stable, these fall back to
returning the span associated with resolution behavior, since the source
location is only cosmetic. This is a reversal of the previous fallback
implementation, which preserved source location because it does not
track resolution location. The differnce is only observable with
`span_locations` enabled.

These methods were stabilized in Rust in
rust-lang/rust#69041
kevinmehall added a commit to kevinmehall/proc-macro2 that referenced this pull request May 20, 2020
On compilers prior to 1.45 where this is not stable, these fall back to
returning the span associated with resolution behavior, since the source
location is only cosmetic. This is a reversal of the previous fallback
implementation, which preserved source location because it does not
track resolution location. The differnce is only observable with
`span_locations` enabled.

These methods were stabilized in Rust in
rust-lang/rust#69041
BoredApe8461 added a commit to BoredApe8461/proc-macro2 that referenced this pull request Aug 12, 2024
On compilers prior to 1.45 where this is not stable, these fall back to
returning the span associated with resolution behavior, since the source
location is only cosmetic. This is a reversal of the previous fallback
implementation, which preserved source location because it does not
track resolution location. The differnce is only observable with
`span_locations` enabled.

These methods were stabilized in Rust in
rust-lang/rust#69041
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.