proc_macro: Update Span::def_site
to use the proc macro definition location
Which is no longer dummy and is available from metadata now.
This commit is contained in:
parent
2065ee9acc
commit
c476b55e52
6 changed files with 143 additions and 41 deletions
|
@ -360,12 +360,11 @@ pub(crate) struct Rustc<'a> {
|
||||||
|
|
||||||
impl<'a> Rustc<'a> {
|
impl<'a> Rustc<'a> {
|
||||||
pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
|
pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
|
||||||
// No way to determine def location for a proc macro right now, so use call location.
|
let expn_data = cx.current_expansion.id.expn_data();
|
||||||
let location = cx.current_expansion.id.expn_data().call_site;
|
|
||||||
Rustc {
|
Rustc {
|
||||||
sess: cx.parse_sess,
|
sess: cx.parse_sess,
|
||||||
def_site: cx.with_def_site_ctxt(location),
|
def_site: cx.with_def_site_ctxt(expn_data.def_site),
|
||||||
call_site: cx.with_call_site_ctxt(location),
|
call_site: cx.with_call_site_ctxt(expn_data.call_site),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -375,10 +375,11 @@ impl<'a> Parser<'a> {
|
||||||
if let Some(directory) = directory {
|
if let Some(directory) = directory {
|
||||||
parser.directory = directory;
|
parser.directory = directory;
|
||||||
} else if !parser.token.span.is_dummy() {
|
} else if !parser.token.span.is_dummy() {
|
||||||
if let FileName::Real(mut path) =
|
if let Some(FileName::Real(path)) =
|
||||||
sess.source_map().span_to_unmapped_path(parser.token.span) {
|
&sess.source_map().lookup_char_pos(parser.token.span.lo()).file.unmapped_path {
|
||||||
path.pop();
|
if let Some(directory_path) = path.parent() {
|
||||||
parser.directory.path = Cow::from(path);
|
parser.directory.path = Cow::from(directory_path.to_path_buf());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
|
|
||||||
use proc_macro::{quote, Span, TokenStream};
|
use proc_macro::{quote, Span, TokenStream, TokenTree};
|
||||||
|
|
||||||
fn assert_same_span(a: Span, b: Span) {
|
fn assert_same_span(a: Span, b: Span) {
|
||||||
assert_eq!(a.start(), b.start());
|
assert_eq!(a.start(), b.start());
|
||||||
|
@ -24,13 +24,23 @@ pub fn make_foo(_: TokenStream) -> TokenStream {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check that all spans are equal.
|
// Check that all spans are equal.
|
||||||
let mut span = None;
|
// FIXME: `quote!` gives def-site spans to idents and literals,
|
||||||
|
// but leaves (default) call-site spans on groups and punctuation.
|
||||||
|
let mut span_call = None;
|
||||||
|
let mut span_def = None;
|
||||||
for tt in result.clone() {
|
for tt in result.clone() {
|
||||||
match span {
|
match tt {
|
||||||
None => span = Some(tt.span()),
|
TokenTree::Ident(..) | TokenTree::Literal(..) => match span_def {
|
||||||
|
None => span_def = Some(tt.span()),
|
||||||
|
Some(span) => assert_same_span(tt.span(), span),
|
||||||
|
}
|
||||||
|
TokenTree::Punct(..) | TokenTree::Group(..) => match span_call {
|
||||||
|
None => span_call = Some(tt.span()),
|
||||||
Some(span) => assert_same_span(tt.span(), span),
|
Some(span) => assert_same_span(tt.span(), span),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,14 @@ error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fra
|
||||||
--> $DIR/same-sequence-span.rs:20:1
|
--> $DIR/same-sequence-span.rs:20:1
|
||||||
|
|
|
|
||||||
LL | proc_macro_sequence::make_foo!();
|
LL | proc_macro_sequence::make_foo!();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^--------------------------------
|
||||||
| |
|
| |
|
||||||
| not allowed after `expr` fragments
|
| _in this macro invocation
|
||||||
| in this macro invocation
|
| |
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | fn main() {}
|
||||||
|
... |
|
||||||
|
|
|
|
||||||
= note: allowed there are: `=>`, `,` or `;`
|
= note: allowed there are: `=>`, `,` or `;`
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,19 @@
|
||||||
error: hello to you, too!
|
error: hello to you, too!
|
||||||
--> $DIR/multispan.rs:14:5
|
--> $DIR/auxiliary/multispan.rs:31:1
|
||||||
|
|
|
||||||
|
LL | / pub fn hello(input: TokenStream) -> TokenStream {
|
||||||
|
LL | | if let Err(diag) = parse(input) {
|
||||||
|
LL | | diag.emit();
|
||||||
|
LL | | }
|
||||||
|
LL | |
|
||||||
|
LL | | TokenStream::new()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
::: $DIR/multispan.rs:14:5
|
||||||
|
|
|
|
||||||
LL | hello!(hi);
|
LL | hello!(hi);
|
||||||
| ^^^^^^^^^^^ in this macro invocation
|
| ----------- in this macro invocation
|
||||||
|
|
|
|
||||||
note: found these 'hi's
|
note: found these 'hi's
|
||||||
--> $DIR/multispan.rs:14:12
|
--> $DIR/multispan.rs:14:12
|
||||||
|
@ -11,10 +22,21 @@ LL | hello!(hi);
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: hello to you, too!
|
error: hello to you, too!
|
||||||
--> $DIR/multispan.rs:17:5
|
--> $DIR/auxiliary/multispan.rs:31:1
|
||||||
|
|
|
||||||
|
LL | / pub fn hello(input: TokenStream) -> TokenStream {
|
||||||
|
LL | | if let Err(diag) = parse(input) {
|
||||||
|
LL | | diag.emit();
|
||||||
|
LL | | }
|
||||||
|
LL | |
|
||||||
|
LL | | TokenStream::new()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
::: $DIR/multispan.rs:17:5
|
||||||
|
|
|
|
||||||
LL | hello!(hi hi);
|
LL | hello!(hi hi);
|
||||||
| ^^^^^^^^^^^^^^ in this macro invocation
|
| -------------- in this macro invocation
|
||||||
|
|
|
|
||||||
note: found these 'hi's
|
note: found these 'hi's
|
||||||
--> $DIR/multispan.rs:17:12
|
--> $DIR/multispan.rs:17:12
|
||||||
|
@ -23,10 +45,21 @@ LL | hello!(hi hi);
|
||||||
| ^^ ^^
|
| ^^ ^^
|
||||||
|
|
||||||
error: hello to you, too!
|
error: hello to you, too!
|
||||||
--> $DIR/multispan.rs:20:5
|
--> $DIR/auxiliary/multispan.rs:31:1
|
||||||
|
|
|
||||||
|
LL | / pub fn hello(input: TokenStream) -> TokenStream {
|
||||||
|
LL | | if let Err(diag) = parse(input) {
|
||||||
|
LL | | diag.emit();
|
||||||
|
LL | | }
|
||||||
|
LL | |
|
||||||
|
LL | | TokenStream::new()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
::: $DIR/multispan.rs:20:5
|
||||||
|
|
|
|
||||||
LL | hello!(hi hi hi);
|
LL | hello!(hi hi hi);
|
||||||
| ^^^^^^^^^^^^^^^^^ in this macro invocation
|
| ----------------- in this macro invocation
|
||||||
|
|
|
|
||||||
note: found these 'hi's
|
note: found these 'hi's
|
||||||
--> $DIR/multispan.rs:20:12
|
--> $DIR/multispan.rs:20:12
|
||||||
|
@ -35,10 +68,21 @@ LL | hello!(hi hi hi);
|
||||||
| ^^ ^^ ^^
|
| ^^ ^^ ^^
|
||||||
|
|
||||||
error: hello to you, too!
|
error: hello to you, too!
|
||||||
--> $DIR/multispan.rs:23:5
|
--> $DIR/auxiliary/multispan.rs:31:1
|
||||||
|
|
|
||||||
|
LL | / pub fn hello(input: TokenStream) -> TokenStream {
|
||||||
|
LL | | if let Err(diag) = parse(input) {
|
||||||
|
LL | | diag.emit();
|
||||||
|
LL | | }
|
||||||
|
LL | |
|
||||||
|
LL | | TokenStream::new()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
::: $DIR/multispan.rs:23:5
|
||||||
|
|
|
|
||||||
LL | hello!(hi hey hi yo hi beep beep hi hi);
|
LL | hello!(hi hey hi yo hi beep beep hi hi);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
|
| ---------------------------------------- in this macro invocation
|
||||||
|
|
|
|
||||||
note: found these 'hi's
|
note: found these 'hi's
|
||||||
--> $DIR/multispan.rs:23:12
|
--> $DIR/multispan.rs:23:12
|
||||||
|
@ -47,10 +91,21 @@ LL | hello!(hi hey hi yo hi beep beep hi hi);
|
||||||
| ^^ ^^ ^^ ^^ ^^
|
| ^^ ^^ ^^ ^^ ^^
|
||||||
|
|
||||||
error: hello to you, too!
|
error: hello to you, too!
|
||||||
--> $DIR/multispan.rs:24:5
|
--> $DIR/auxiliary/multispan.rs:31:1
|
||||||
|
|
|
||||||
|
LL | / pub fn hello(input: TokenStream) -> TokenStream {
|
||||||
|
LL | | if let Err(diag) = parse(input) {
|
||||||
|
LL | | diag.emit();
|
||||||
|
LL | | }
|
||||||
|
LL | |
|
||||||
|
LL | | TokenStream::new()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
::: $DIR/multispan.rs:24:5
|
||||||
|
|
|
|
||||||
LL | hello!(hi there, hi how are you? hi... hi.);
|
LL | hello!(hi there, hi how are you? hi... hi.);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
|
| -------------------------------------------- in this macro invocation
|
||||||
|
|
|
|
||||||
note: found these 'hi's
|
note: found these 'hi's
|
||||||
--> $DIR/multispan.rs:24:12
|
--> $DIR/multispan.rs:24:12
|
||||||
|
@ -59,10 +114,21 @@ LL | hello!(hi there, hi how are you? hi... hi.);
|
||||||
| ^^ ^^ ^^ ^^
|
| ^^ ^^ ^^ ^^
|
||||||
|
|
||||||
error: hello to you, too!
|
error: hello to you, too!
|
||||||
--> $DIR/multispan.rs:25:5
|
--> $DIR/auxiliary/multispan.rs:31:1
|
||||||
|
|
|
||||||
|
LL | / pub fn hello(input: TokenStream) -> TokenStream {
|
||||||
|
LL | | if let Err(diag) = parse(input) {
|
||||||
|
LL | | diag.emit();
|
||||||
|
LL | | }
|
||||||
|
LL | |
|
||||||
|
LL | | TokenStream::new()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
::: $DIR/multispan.rs:25:5
|
||||||
|
|
|
|
||||||
LL | hello!(whoah. hi di hi di ho);
|
LL | hello!(whoah. hi di hi di ho);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
|
| ------------------------------ in this macro invocation
|
||||||
|
|
|
|
||||||
note: found these 'hi's
|
note: found these 'hi's
|
||||||
--> $DIR/multispan.rs:25:19
|
--> $DIR/multispan.rs:25:19
|
||||||
|
@ -71,10 +137,21 @@ LL | hello!(whoah. hi di hi di ho);
|
||||||
| ^^ ^^
|
| ^^ ^^
|
||||||
|
|
||||||
error: hello to you, too!
|
error: hello to you, too!
|
||||||
--> $DIR/multispan.rs:26:5
|
--> $DIR/auxiliary/multispan.rs:31:1
|
||||||
|
|
|
||||||
|
LL | / pub fn hello(input: TokenStream) -> TokenStream {
|
||||||
|
LL | | if let Err(diag) = parse(input) {
|
||||||
|
LL | | diag.emit();
|
||||||
|
LL | | }
|
||||||
|
LL | |
|
||||||
|
LL | | TokenStream::new()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
::: $DIR/multispan.rs:26:5
|
||||||
|
|
|
|
||||||
LL | hello!(hi good hi and good bye);
|
LL | hello!(hi good hi and good bye);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
|
| -------------------------------- in this macro invocation
|
||||||
|
|
|
|
||||||
note: found these 'hi's
|
note: found these 'hi's
|
||||||
--> $DIR/multispan.rs:26:12
|
--> $DIR/multispan.rs:26:12
|
||||||
|
|
|
@ -1,8 +1,19 @@
|
||||||
error: found 2 equal signs, need exactly 3
|
error: found 2 equal signs, need exactly 3
|
||||||
--> $DIR/three-equals.rs:15:5
|
--> $DIR/auxiliary/three-equals.rs:42:1
|
||||||
|
|
|
||||||
|
LL | / pub fn three_equals(input: TokenStream) -> TokenStream {
|
||||||
|
LL | | if let Err(diag) = parse(input) {
|
||||||
|
LL | | diag.emit();
|
||||||
|
LL | | return TokenStream::new();
|
||||||
|
... |
|
||||||
|
LL | | "3".parse().unwrap()
|
||||||
|
LL | | }
|
||||||
|
| |_^
|
||||||
|
|
|
||||||
|
::: $DIR/three-equals.rs:15:5
|
||||||
|
|
|
|
||||||
LL | three_equals!(==);
|
LL | three_equals!(==);
|
||||||
| ^^^^^^^^^^^^^^^^^^ in this macro invocation
|
| ------------------ in this macro invocation
|
||||||
|
|
|
|
||||||
= help: input must be: `===`
|
= help: input must be: `===`
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue