Skip to content

Commit 8227a93

Browse files
committed
Point at macro definition when no rules expect token
1 parent a66dc8a commit 8227a93

21 files changed

+256
-82
lines changed

src/libsyntax/ext/base.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,13 @@ impl<F> AttrProcMacro for F
247247

248248
/// Represents a thing that maps token trees to Macro Results
249249
pub trait TTMacroExpander {
250-
fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, span: Span, input: TokenStream)
251-
-> Box<dyn MacResult+'cx>;
250+
fn expand<'cx>(
251+
&self,
252+
ecx: &'cx mut ExtCtxt,
253+
span: Span,
254+
input: TokenStream,
255+
def_span: Option<Span>,
256+
) -> Box<dyn MacResult+'cx>;
252257
}
253258

254259
pub type MacroExpanderFn =
@@ -259,8 +264,13 @@ impl<F> TTMacroExpander for F
259264
where F: for<'cx> Fn(&'cx mut ExtCtxt, Span, &[tokenstream::TokenTree])
260265
-> Box<dyn MacResult+'cx>
261266
{
262-
fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, span: Span, input: TokenStream)
263-
-> Box<dyn MacResult+'cx> {
267+
fn expand<'cx>(
268+
&self,
269+
ecx: &'cx mut ExtCtxt,
270+
span: Span,
271+
input: TokenStream,
272+
_def_span: Option<Span>,
273+
) -> Box<dyn MacResult+'cx> {
264274
struct AvoidInterpolatedIdents;
265275

266276
impl Folder for AvoidInterpolatedIdents {

src/libsyntax/ext/expand.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
764764
edition) {
765765
dummy_span
766766
} else {
767-
kind.make_from(expander.expand(self.cx, span, mac.node.stream()))
767+
kind.make_from(expander.expand(self.cx, span, mac.node.stream(), None))
768768
}
769769
}
770770

@@ -785,7 +785,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
785785
edition) {
786786
dummy_span
787787
} else {
788-
kind.make_from(expander.expand(self.cx, span, mac.node.stream()))
788+
kind.make_from(expander.expand(
789+
self.cx,
790+
span,
791+
mac.node.stream(),
792+
def_info.map(|(_, s)| s),
793+
))
789794
}
790795
}
791796

src/libsyntax/ext/tt/macro_rules.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,19 @@ struct MacroRulesMacroExpander {
7474
}
7575

7676
impl TTMacroExpander for MacroRulesMacroExpander {
77-
fn expand<'cx>(&self,
78-
cx: &'cx mut ExtCtxt,
79-
sp: Span,
80-
input: TokenStream)
81-
-> Box<dyn MacResult+'cx> {
77+
fn expand<'cx>(
78+
&self,
79+
cx: &'cx mut ExtCtxt,
80+
sp: Span,
81+
input: TokenStream,
82+
def_span: Option<Span>,
83+
) -> Box<dyn MacResult+'cx> {
8284
if !self.valid {
8385
return DummyResult::any(sp);
8486
}
8587
generic_extension(cx,
8688
sp,
89+
def_span,
8790
self.name,
8891
input,
8992
&self.lhses,
@@ -99,6 +102,7 @@ fn trace_macros_note(cx: &mut ExtCtxt, sp: Span, message: String) {
99102
/// Given `lhses` and `rhses`, this is the new macro we create
100103
fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
101104
sp: Span,
105+
def_span: Option<Span>,
102106
name: ast::Ident,
103107
arg: TokenStream,
104108
lhses: &[quoted::TokenTree],
@@ -178,7 +182,14 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
178182
}
179183

180184
let best_fail_msg = parse_failure_msg(best_fail_tok.expect("ran no matchers"));
181-
let mut err = cx.struct_span_err(best_fail_spot.substitute_dummy(sp), &best_fail_msg);
185+
let span = best_fail_spot.substitute_dummy(sp);
186+
let mut err = cx.struct_span_err(span, &best_fail_msg);
187+
err.span_label(span, best_fail_msg);
188+
if let Some(sp) = def_span {
189+
if cx.source_map().span_to_filename(sp).is_real() && !sp.is_dummy() {
190+
err.span_label(sp, "when calling this macro");
191+
}
192+
}
182193

183194
// Check whether there's a missing comma in this macro call, like `println!("{}" a);`
184195
if let Some((arg, comma_span)) = arg.add_comma() {
@@ -189,7 +200,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
189200
};
190201
match TokenTree::parse(cx, lhs_tt, arg.clone()) {
191202
Success(_) => {
192-
if comma_span == DUMMY_SP {
203+
if comma_span.is_dummy() {
193204
err.note("you might be missing a comma");
194205
} else {
195206
err.span_suggestion_short_with_applicability(

src/test/run-pass-fulldeps/auxiliary/plugin_args.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ impl TTMacroExpander for Expander {
3838
fn expand<'cx>(&self,
3939
ecx: &'cx mut ExtCtxt,
4040
sp: Span,
41-
_: TokenStream) -> Box<MacResult+'cx> {
41+
_: TokenStream,
42+
_: Option<Span>) -> Box<MacResult+'cx> {
4243
let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i))
4344
.collect::<Vec<_>>().join(", ");
4445
MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args)))

src/test/ui/editions/edition-keywords-2015-2015-parsing.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error: no rules expected the token `r#async`
22
--> $DIR/edition-keywords-2015-2015-parsing.rs:22:31
33
|
44
LL | r#async = consumes_async!(r#async); //~ ERROR no rules expected the token `r#async`
5-
| ^^^^^^^
5+
| ^^^^^^^ no rules expected the token `r#async`
66

77
error: no rules expected the token `async`
88
--> $DIR/edition-keywords-2015-2015-parsing.rs:23:35
99
|
1010
LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
11-
| ^^^^^
11+
| ^^^^^ no rules expected the token `async`
1212

1313
error: aborting due to 2 previous errors
1414

src/test/ui/editions/edition-keywords-2015-2018-parsing.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ error: no rules expected the token `r#async`
22
--> $DIR/edition-keywords-2015-2018-parsing.rs:22:31
33
|
44
LL | r#async = consumes_async!(r#async); //~ ERROR no rules expected the token `r#async`
5-
| ^^^^^^^
5+
| ^^^^^^^ no rules expected the token `r#async`
66

77
error: no rules expected the token `async`
88
--> $DIR/edition-keywords-2015-2018-parsing.rs:23:35
99
|
1010
LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
11-
| ^^^^^
11+
| ^^^^^ no rules expected the token `async`
1212

1313
error: aborting due to 2 previous errors
1414

src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ error: no rules expected the token `r#async`
1414
--> $DIR/edition-keywords-2018-2015-parsing.rs:22:31
1515
|
1616
LL | r#async = consumes_async!(r#async); //~ ERROR no rules expected the token `r#async`
17-
| ^^^^^^^
17+
| ^^^^^^^ no rules expected the token `r#async`
1818

1919
error: no rules expected the token `async`
2020
--> $DIR/edition-keywords-2018-2015-parsing.rs:23:35
2121
|
2222
LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
23-
| ^^^^^
23+
| ^^^^^ no rules expected the token `async`
2424

2525
error: expected one of `move`, `|`, or `||`, found `<eof>`
2626
--> <::edition_kw_macro_2015::passes_ident macros>:1:22

src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ error: no rules expected the token `r#async`
1414
--> $DIR/edition-keywords-2018-2018-parsing.rs:22:31
1515
|
1616
LL | r#async = consumes_async!(r#async); //~ ERROR no rules expected the token `r#async`
17-
| ^^^^^^^
17+
| ^^^^^^^ no rules expected the token `r#async`
1818

1919
error: no rules expected the token `async`
2020
--> $DIR/edition-keywords-2018-2018-parsing.rs:23:35
2121
|
2222
LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
23-
| ^^^^^
23+
| ^^^^^ no rules expected the token `async`
2424

2525
error: expected one of `move`, `|`, or `||`, found `<eof>`
2626
--> <::edition_kw_macro_2018::passes_ident macros>:1:22
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
error: unexpected end of macro invocation
22
--> $DIR/empty-comment.rs:20:5
33
|
4-
LL | one_arg_macro!(/**/); //~ ERROR unexpected end
5-
| ^^^^^^^^^^^^^^^^^^^^^
4+
LL | / macro_rules! one_arg_macro {
5+
LL | | ($fmt:expr) => (print!(concat!($fmt, "/n")));
6+
LL | | }
7+
| |_- when calling this macro
8+
...
9+
LL | one_arg_macro!(/**/); //~ ERROR unexpected end
10+
| ^^^^^^^^^^^^^^^^^^^^^ unexpected end of macro invocation
611

712
error: aborting due to previous error
813

src/test/ui/fail-simple.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error: no rules expected the token `@`
22
--> $DIR/fail-simple.rs:12:12
33
|
44
LL | panic!(@); //~ ERROR no rules expected the token `@`
5-
| ^
5+
| ^ no rules expected the token `@`
66

77
error: aborting due to previous error
88

src/test/ui/issues/issue-7970a.stderr

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
error: unexpected end of macro invocation
22
--> $DIR/issue-7970a.rs:16:5
33
|
4-
LL | one_arg_macro!();
5-
| ^^^^^^^^^^^^^^^^^
4+
LL | / macro_rules! one_arg_macro {
5+
LL | | ($fmt:expr) => (print!(concat!($fmt, "/n")));
6+
LL | | }
7+
| |_- when calling this macro
8+
...
9+
LL | one_arg_macro!();
10+
| ^^^^^^^^^^^^^^^^^ unexpected end of macro invocation
611

712
error: aborting due to previous error
813

src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,41 @@ LL | ($(a)?*) => {}
5151
error: no rules expected the token `?`
5252
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:41:11
5353
|
54-
LL | foo!(a?); //~ ERROR no rules expected the token `?`
55-
| ^
54+
LL | / macro_rules! foo {
55+
LL | | ($(a)?) => {}
56+
LL | | //~^ERROR using the `?` macro Kleene operator for
57+
LL | | //~|ERROR expected `*` or `+`
58+
LL | | }
59+
| |_- when calling this macro
60+
...
61+
LL | foo!(a?); //~ ERROR no rules expected the token `?`
62+
| ^ no rules expected the token `?`
5663

5764
error: no rules expected the token `?`
5865
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:42:11
5966
|
60-
LL | foo!(a?a); //~ ERROR no rules expected the token `?`
61-
| ^
67+
LL | / macro_rules! foo {
68+
LL | | ($(a)?) => {}
69+
LL | | //~^ERROR using the `?` macro Kleene operator for
70+
LL | | //~|ERROR expected `*` or `+`
71+
LL | | }
72+
| |_- when calling this macro
73+
...
74+
LL | foo!(a?a); //~ ERROR no rules expected the token `?`
75+
| ^ no rules expected the token `?`
6276

6377
error: no rules expected the token `?`
6478
--> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:43:11
6579
|
66-
LL | foo!(a?a?a); //~ ERROR no rules expected the token `?`
67-
| ^
80+
LL | / macro_rules! foo {
81+
LL | | ($(a)?) => {}
82+
LL | | //~^ERROR using the `?` macro Kleene operator for
83+
LL | | //~|ERROR expected `*` or `+`
84+
LL | | }
85+
| |_- when calling this macro
86+
...
87+
LL | foo!(a?a?a); //~ ERROR no rules expected the token `?`
88+
| ^ no rules expected the token `?`
6889

6990
error: aborting due to 10 previous errors
7091

0 commit comments

Comments
 (0)