Skip to content

Commit

Permalink
Rollup merge of #69041 - petrochenkov:stabmodispan, r=Amanieu
Browse files Browse the repository at this point in the history
proc_macro: Stabilize `Span::resolved_at` and `Span::located_at`

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`](#68716).

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

r? @dtolnay
  • Loading branch information
Dylan-DPC authored Apr 25, 2020
2 parents b613c98 + 966a295 commit 7b7c63c
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/libproc_macro/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
pub fn resolved_at(&self, other: Span) -> Span {
Span(self.0.resolved_at(other.0))
}

/// Creates a new span with the same name resolution behavior as `self` but
/// with the line/column information of `other`.
#[unstable(feature = "proc_macro_span", issue = "54725")]
#[stable(feature = "proc_macro_span_located_at", since = "1.43.0")]
pub fn located_at(&self, other: Span) -> Span {
other.resolved_at(*self)
}
Expand Down
32 changes: 32 additions & 0 deletions src/test/ui/proc-macro/auxiliary/resolved-located-at.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// force-host
// no-prefer-dynamic

#![feature(proc_macro_def_site)]
#![feature(proc_macro_diagnostic)]
#![feature(proc_macro_hygiene)]
#![feature(proc_macro_quote)]
#![crate_type = "proc-macro"]

extern crate proc_macro;
use proc_macro::*;

#[proc_macro]
pub fn resolve_located_at(input: TokenStream) -> TokenStream {
match &*input.into_iter().collect::<Vec<_>>() {
[a, b, ..] => {
// The error is reported at input `a`.
let mut diag = Diagnostic::new(Level::Error, "expected error");
diag.set_spans(Span::def_site().located_at(a.span()));
diag.emit();

// Resolves to `struct S;` at def site, but the error is reported at input `b`.
let s = TokenTree::Ident(Ident::new("S", b.span().resolved_at(Span::def_site())));
quote!({
struct S;

$s
})
}
_ => panic!("unexpected input"),
}
}
12 changes: 12 additions & 0 deletions src/test/ui/proc-macro/resolved-located-at.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// aux-build:resolved-located-at.rs

#![feature(proc_macro_hygiene)]

#[macro_use]
extern crate resolved_located_at;

fn main() {
resolve_located_at!(a b)
//~^ ERROR expected error
//~| ERROR mismatched types
}
21 changes: 21 additions & 0 deletions src/test/ui/proc-macro/resolved-located-at.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
error: expected error
--> $DIR/resolved-located-at.rs:9:25
|
LL | resolve_located_at!(a b)
| ^
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0308]: mismatched types
--> $DIR/resolved-located-at.rs:9:27
|
LL | fn main() {
| - expected `()` because of default return type
LL | resolve_located_at!(a b)
| ^ expected `()`, found struct `main::S`
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0308`.

0 comments on commit 7b7c63c

Please sign in to comment.