Skip to content

Commit c476b55

Browse files
committed
proc_macro: Update Span::def_site to use the proc macro definition location
Which is no longer dummy and is available from metadata now.
1 parent 2065ee9 commit c476b55

File tree

6 files changed

+151
-49
lines changed

6 files changed

+151
-49
lines changed

src/libsyntax/ext/proc_macro_server.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -360,12 +360,11 @@ pub(crate) struct Rustc<'a> {
360360

361361
impl<'a> Rustc<'a> {
362362
pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
363-
// No way to determine def location for a proc macro right now, so use call location.
364-
let location = cx.current_expansion.id.expn_data().call_site;
363+
let expn_data = cx.current_expansion.id.expn_data();
365364
Rustc {
366365
sess: cx.parse_sess,
367-
def_site: cx.with_def_site_ctxt(location),
368-
call_site: cx.with_call_site_ctxt(location),
366+
def_site: cx.with_def_site_ctxt(expn_data.def_site),
367+
call_site: cx.with_call_site_ctxt(expn_data.call_site),
369368
}
370369
}
371370

src/libsyntax/parse/parser.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -375,10 +375,11 @@ impl<'a> Parser<'a> {
375375
if let Some(directory) = directory {
376376
parser.directory = directory;
377377
} else if !parser.token.span.is_dummy() {
378-
if let FileName::Real(mut path) =
379-
sess.source_map().span_to_unmapped_path(parser.token.span) {
380-
path.pop();
381-
parser.directory.path = Cow::from(path);
378+
if let Some(FileName::Real(path)) =
379+
&sess.source_map().lookup_char_pos(parser.token.span.lo()).file.unmapped_path {
380+
if let Some(directory_path) = path.parent() {
381+
parser.directory.path = Cow::from(directory_path.to_path_buf());
382+
}
382383
}
383384
}
384385

src/test/ui/macros/auxiliary/proc_macro_sequence.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
extern crate proc_macro;
88

9-
use proc_macro::{quote, Span, TokenStream};
9+
use proc_macro::{quote, Span, TokenStream, TokenTree};
1010

1111
fn assert_same_span(a: Span, b: Span) {
1212
assert_eq!(a.start(), b.start());
@@ -24,12 +24,22 @@ pub fn make_foo(_: TokenStream) -> TokenStream {
2424
};
2525

2626
// Check that all spans are equal.
27-
let mut span = None;
27+
// FIXME: `quote!` gives def-site spans to idents and literals,
28+
// but leaves (default) call-site spans on groups and punctuation.
29+
let mut span_call = None;
30+
let mut span_def = None;
2831
for tt in result.clone() {
29-
match span {
30-
None => span = Some(tt.span()),
31-
Some(span) => assert_same_span(tt.span(), span),
32+
match tt {
33+
TokenTree::Ident(..) | TokenTree::Literal(..) => match span_def {
34+
None => span_def = Some(tt.span()),
35+
Some(span) => assert_same_span(tt.span(), span),
36+
}
37+
TokenTree::Punct(..) | TokenTree::Group(..) => match span_call {
38+
None => span_call = Some(tt.span()),
39+
Some(span) => assert_same_span(tt.span(), span),
40+
}
3241
}
42+
3343
}
3444

3545
result

src/test/ui/macros/same-sequence-span.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@ LL | $(= $z:tt)*
1717
error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
1818
--> $DIR/same-sequence-span.rs:20:1
1919
|
20-
LL | proc_macro_sequence::make_foo!();
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20+
LL | proc_macro_sequence::make_foo!();
21+
| ^--------------------------------
22+
| |
23+
| _in this macro invocation
2224
| |
23-
| not allowed after `expr` fragments
24-
| in this macro invocation
25+
LL | |
26+
LL | |
27+
LL | | fn main() {}
28+
... |
2529
|
2630
= note: allowed there are: `=>`, `,` or `;`
2731

src/test/ui/proc-macro/multispan.stderr

+105-28
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
error: hello to you, too!
2-
--> $DIR/multispan.rs:14:5
3-
|
4-
LL | hello!(hi);
5-
| ^^^^^^^^^^^ in this macro invocation
2+
--> $DIR/auxiliary/multispan.rs:31:1
3+
|
4+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
5+
LL | | if let Err(diag) = parse(input) {
6+
LL | | diag.emit();
7+
LL | | }
8+
LL | |
9+
LL | | TokenStream::new()
10+
LL | | }
11+
| |_^
12+
|
13+
::: $DIR/multispan.rs:14:5
14+
|
15+
LL | hello!(hi);
16+
| ----------- in this macro invocation
617
|
718
note: found these 'hi's
819
--> $DIR/multispan.rs:14:12
@@ -11,10 +22,21 @@ LL | hello!(hi);
1122
| ^^
1223

1324
error: hello to you, too!
14-
--> $DIR/multispan.rs:17:5
15-
|
16-
LL | hello!(hi hi);
17-
| ^^^^^^^^^^^^^^ in this macro invocation
25+
--> $DIR/auxiliary/multispan.rs:31:1
26+
|
27+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
28+
LL | | if let Err(diag) = parse(input) {
29+
LL | | diag.emit();
30+
LL | | }
31+
LL | |
32+
LL | | TokenStream::new()
33+
LL | | }
34+
| |_^
35+
|
36+
::: $DIR/multispan.rs:17:5
37+
|
38+
LL | hello!(hi hi);
39+
| -------------- in this macro invocation
1840
|
1941
note: found these 'hi's
2042
--> $DIR/multispan.rs:17:12
@@ -23,10 +45,21 @@ LL | hello!(hi hi);
2345
| ^^ ^^
2446

2547
error: hello to you, too!
26-
--> $DIR/multispan.rs:20:5
27-
|
28-
LL | hello!(hi hi hi);
29-
| ^^^^^^^^^^^^^^^^^ in this macro invocation
48+
--> $DIR/auxiliary/multispan.rs:31:1
49+
|
50+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
51+
LL | | if let Err(diag) = parse(input) {
52+
LL | | diag.emit();
53+
LL | | }
54+
LL | |
55+
LL | | TokenStream::new()
56+
LL | | }
57+
| |_^
58+
|
59+
::: $DIR/multispan.rs:20:5
60+
|
61+
LL | hello!(hi hi hi);
62+
| ----------------- in this macro invocation
3063
|
3164
note: found these 'hi's
3265
--> $DIR/multispan.rs:20:12
@@ -35,10 +68,21 @@ LL | hello!(hi hi hi);
3568
| ^^ ^^ ^^
3669

3770
error: hello to you, too!
38-
--> $DIR/multispan.rs:23:5
39-
|
40-
LL | hello!(hi hey hi yo hi beep beep hi hi);
41-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
71+
--> $DIR/auxiliary/multispan.rs:31:1
72+
|
73+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
74+
LL | | if let Err(diag) = parse(input) {
75+
LL | | diag.emit();
76+
LL | | }
77+
LL | |
78+
LL | | TokenStream::new()
79+
LL | | }
80+
| |_^
81+
|
82+
::: $DIR/multispan.rs:23:5
83+
|
84+
LL | hello!(hi hey hi yo hi beep beep hi hi);
85+
| ---------------------------------------- in this macro invocation
4286
|
4387
note: found these 'hi's
4488
--> $DIR/multispan.rs:23:12
@@ -47,10 +91,21 @@ LL | hello!(hi hey hi yo hi beep beep hi hi);
4791
| ^^ ^^ ^^ ^^ ^^
4892

4993
error: hello to you, too!
50-
--> $DIR/multispan.rs:24:5
51-
|
52-
LL | hello!(hi there, hi how are you? hi... hi.);
53-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
94+
--> $DIR/auxiliary/multispan.rs:31:1
95+
|
96+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
97+
LL | | if let Err(diag) = parse(input) {
98+
LL | | diag.emit();
99+
LL | | }
100+
LL | |
101+
LL | | TokenStream::new()
102+
LL | | }
103+
| |_^
104+
|
105+
::: $DIR/multispan.rs:24:5
106+
|
107+
LL | hello!(hi there, hi how are you? hi... hi.);
108+
| -------------------------------------------- in this macro invocation
54109
|
55110
note: found these 'hi's
56111
--> $DIR/multispan.rs:24:12
@@ -59,10 +114,21 @@ LL | hello!(hi there, hi how are you? hi... hi.);
59114
| ^^ ^^ ^^ ^^
60115

61116
error: hello to you, too!
62-
--> $DIR/multispan.rs:25:5
63-
|
64-
LL | hello!(whoah. hi di hi di ho);
65-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
117+
--> $DIR/auxiliary/multispan.rs:31:1
118+
|
119+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
120+
LL | | if let Err(diag) = parse(input) {
121+
LL | | diag.emit();
122+
LL | | }
123+
LL | |
124+
LL | | TokenStream::new()
125+
LL | | }
126+
| |_^
127+
|
128+
::: $DIR/multispan.rs:25:5
129+
|
130+
LL | hello!(whoah. hi di hi di ho);
131+
| ------------------------------ in this macro invocation
66132
|
67133
note: found these 'hi's
68134
--> $DIR/multispan.rs:25:19
@@ -71,10 +137,21 @@ LL | hello!(whoah. hi di hi di ho);
71137
| ^^ ^^
72138

73139
error: hello to you, too!
74-
--> $DIR/multispan.rs:26:5
75-
|
76-
LL | hello!(hi good hi and good bye);
77-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
140+
--> $DIR/auxiliary/multispan.rs:31:1
141+
|
142+
LL | / pub fn hello(input: TokenStream) -> TokenStream {
143+
LL | | if let Err(diag) = parse(input) {
144+
LL | | diag.emit();
145+
LL | | }
146+
LL | |
147+
LL | | TokenStream::new()
148+
LL | | }
149+
| |_^
150+
|
151+
::: $DIR/multispan.rs:26:5
152+
|
153+
LL | hello!(hi good hi and good bye);
154+
| -------------------------------- in this macro invocation
78155
|
79156
note: found these 'hi's
80157
--> $DIR/multispan.rs:26:12

src/test/ui/proc-macro/three-equals.stderr

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
error: found 2 equal signs, need exactly 3
2-
--> $DIR/three-equals.rs:15:5
3-
|
4-
LL | three_equals!(==);
5-
| ^^^^^^^^^^^^^^^^^^ in this macro invocation
2+
--> $DIR/auxiliary/three-equals.rs:42:1
3+
|
4+
LL | / pub fn three_equals(input: TokenStream) -> TokenStream {
5+
LL | | if let Err(diag) = parse(input) {
6+
LL | | diag.emit();
7+
LL | | return TokenStream::new();
8+
... |
9+
LL | | "3".parse().unwrap()
10+
LL | | }
11+
| |_^
12+
|
13+
::: $DIR/three-equals.rs:15:5
14+
|
15+
LL | three_equals!(==);
16+
| ------------------ in this macro invocation
617
|
718
= help: input must be: `===`
819

0 commit comments

Comments
 (0)