From 8227a938a4970008ec333f6cd66be9d4be0e981c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 23 Oct 2018 17:18:14 -0700 Subject: [PATCH 1/2] Point at macro definition when no rules expect token --- src/libsyntax/ext/base.rs | 18 +++- src/libsyntax/ext/expand.rs | 9 +- src/libsyntax/ext/tt/macro_rules.rs | 25 +++-- .../auxiliary/plugin_args.rs | 3 +- .../edition-keywords-2015-2015-parsing.stderr | 4 +- .../edition-keywords-2015-2018-parsing.stderr | 4 +- .../edition-keywords-2018-2015-parsing.stderr | 4 +- .../edition-keywords-2018-2018-parsing.stderr | 4 +- src/test/ui/empty/empty-comment.stderr | 9 +- src/test/ui/fail-simple.stderr | 2 +- src/test/ui/issues/issue-7970a.stderr | 9 +- ...-at-most-once-rep-2018-feature-gate.stderr | 33 +++++-- .../macros/macro-at-most-once-rep-2018.stderr | 99 ++++++++++++++----- src/test/ui/macros/macro-non-lifetime.stderr | 5 +- src/test/ui/macros/missing-comma.stderr | 64 +++++++++--- .../ui/macros/nonterminal-matching.stderr | 2 +- src/test/ui/macros/trace_faulty_macros.stderr | 13 ++- .../parser/macro/macro-doc-comments-1.stderr | 9 +- .../parser/macro/macro-doc-comments-2.stderr | 9 +- src/test/ui/underscore-ident-matcher.stderr | 11 ++- .../ui/vec/vec-macro-with-comma-only.stderr | 2 +- 21 files changed, 256 insertions(+), 82 deletions(-) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 5bf1a7dd663cc..1701c8da2c5bd 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -247,8 +247,13 @@ impl AttrProcMacro for F /// Represents a thing that maps token trees to Macro Results pub trait TTMacroExpander { - fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, span: Span, input: TokenStream) - -> Box; + fn expand<'cx>( + &self, + ecx: &'cx mut ExtCtxt, + span: Span, + input: TokenStream, + def_span: Option, + ) -> Box; } pub type MacroExpanderFn = @@ -259,8 +264,13 @@ impl TTMacroExpander for F where F: for<'cx> Fn(&'cx mut ExtCtxt, Span, &[tokenstream::TokenTree]) -> Box { - fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, span: Span, input: TokenStream) - -> Box { + fn expand<'cx>( + &self, + ecx: &'cx mut ExtCtxt, + span: Span, + input: TokenStream, + _def_span: Option, + ) -> Box { struct AvoidInterpolatedIdents; impl Folder for AvoidInterpolatedIdents { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9e06384f5a804..46ffdf4eba2da 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -764,7 +764,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { edition) { dummy_span } else { - kind.make_from(expander.expand(self.cx, span, mac.node.stream())) + kind.make_from(expander.expand(self.cx, span, mac.node.stream(), None)) } } @@ -785,7 +785,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> { edition) { dummy_span } else { - kind.make_from(expander.expand(self.cx, span, mac.node.stream())) + kind.make_from(expander.expand( + self.cx, + span, + mac.node.stream(), + def_info.map(|(_, s)| s), + )) } } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 87ade278c685a..41e8cbe550211 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -74,16 +74,19 @@ struct MacroRulesMacroExpander { } impl TTMacroExpander for MacroRulesMacroExpander { - fn expand<'cx>(&self, - cx: &'cx mut ExtCtxt, - sp: Span, - input: TokenStream) - -> Box { + fn expand<'cx>( + &self, + cx: &'cx mut ExtCtxt, + sp: Span, + input: TokenStream, + def_span: Option, + ) -> Box { if !self.valid { return DummyResult::any(sp); } generic_extension(cx, sp, + def_span, self.name, input, &self.lhses, @@ -99,6 +102,7 @@ fn trace_macros_note(cx: &mut ExtCtxt, sp: Span, message: String) { /// Given `lhses` and `rhses`, this is the new macro we create fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, sp: Span, + def_span: Option, name: ast::Ident, arg: TokenStream, lhses: &[quoted::TokenTree], @@ -178,7 +182,14 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, } let best_fail_msg = parse_failure_msg(best_fail_tok.expect("ran no matchers")); - let mut err = cx.struct_span_err(best_fail_spot.substitute_dummy(sp), &best_fail_msg); + let span = best_fail_spot.substitute_dummy(sp); + let mut err = cx.struct_span_err(span, &best_fail_msg); + err.span_label(span, best_fail_msg); + if let Some(sp) = def_span { + if cx.source_map().span_to_filename(sp).is_real() && !sp.is_dummy() { + err.span_label(sp, "when calling this macro"); + } + } // Check whether there's a missing comma in this macro call, like `println!("{}" a);` if let Some((arg, comma_span)) = arg.add_comma() { @@ -189,7 +200,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, }; match TokenTree::parse(cx, lhs_tt, arg.clone()) { Success(_) => { - if comma_span == DUMMY_SP { + if comma_span.is_dummy() { err.note("you might be missing a comma"); } else { err.span_suggestion_short_with_applicability( diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs index ac39118c5f1e0..27169299c8a69 100644 --- a/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs +++ b/src/test/run-pass-fulldeps/auxiliary/plugin_args.rs @@ -38,7 +38,8 @@ impl TTMacroExpander for Expander { fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, sp: Span, - _: TokenStream) -> Box { + _: TokenStream, + _: Option) -> Box { let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i)) .collect::>().join(", "); MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args))) diff --git a/src/test/ui/editions/edition-keywords-2015-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2015-2015-parsing.stderr index a629d13e6c31b..e8f05cbb0ef70 100644 --- a/src/test/ui/editions/edition-keywords-2015-2015-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2015-2015-parsing.stderr @@ -2,13 +2,13 @@ error: no rules expected the token `r#async` --> $DIR/edition-keywords-2015-2015-parsing.rs:22:31 | LL | r#async = consumes_async!(r#async); //~ ERROR no rules expected the token `r#async` - | ^^^^^^^ + | ^^^^^^^ no rules expected the token `r#async` error: no rules expected the token `async` --> $DIR/edition-keywords-2015-2015-parsing.rs:23:35 | LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async` - | ^^^^^ + | ^^^^^ no rules expected the token `async` error: aborting due to 2 previous errors diff --git a/src/test/ui/editions/edition-keywords-2015-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2015-2018-parsing.stderr index ab8a34a4a9e3d..3f5e1137383dd 100644 --- a/src/test/ui/editions/edition-keywords-2015-2018-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2015-2018-parsing.stderr @@ -2,13 +2,13 @@ error: no rules expected the token `r#async` --> $DIR/edition-keywords-2015-2018-parsing.rs:22:31 | LL | r#async = consumes_async!(r#async); //~ ERROR no rules expected the token `r#async` - | ^^^^^^^ + | ^^^^^^^ no rules expected the token `r#async` error: no rules expected the token `async` --> $DIR/edition-keywords-2015-2018-parsing.rs:23:35 | LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async` - | ^^^^^ + | ^^^^^ no rules expected the token `async` error: aborting due to 2 previous errors diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr index 5955410aa106b..b6ff60f1492ea 100644 --- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr @@ -14,13 +14,13 @@ error: no rules expected the token `r#async` --> $DIR/edition-keywords-2018-2015-parsing.rs:22:31 | LL | r#async = consumes_async!(r#async); //~ ERROR no rules expected the token `r#async` - | ^^^^^^^ + | ^^^^^^^ no rules expected the token `r#async` error: no rules expected the token `async` --> $DIR/edition-keywords-2018-2015-parsing.rs:23:35 | LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async` - | ^^^^^ + | ^^^^^ no rules expected the token `async` error: expected one of `move`, `|`, or `||`, found `` --> <::edition_kw_macro_2015::passes_ident macros>:1:22 diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr index 6ea736828f907..ffe666a7e6442 100644 --- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr +++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr @@ -14,13 +14,13 @@ error: no rules expected the token `r#async` --> $DIR/edition-keywords-2018-2018-parsing.rs:22:31 | LL | r#async = consumes_async!(r#async); //~ ERROR no rules expected the token `r#async` - | ^^^^^^^ + | ^^^^^^^ no rules expected the token `r#async` error: no rules expected the token `async` --> $DIR/edition-keywords-2018-2018-parsing.rs:23:35 | LL | r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async` - | ^^^^^ + | ^^^^^ no rules expected the token `async` error: expected one of `move`, `|`, or `||`, found `` --> <::edition_kw_macro_2018::passes_ident macros>:1:22 diff --git a/src/test/ui/empty/empty-comment.stderr b/src/test/ui/empty/empty-comment.stderr index d6990c4eaeb8f..e15f347f49d9c 100644 --- a/src/test/ui/empty/empty-comment.stderr +++ b/src/test/ui/empty/empty-comment.stderr @@ -1,8 +1,13 @@ error: unexpected end of macro invocation --> $DIR/empty-comment.rs:20:5 | -LL | one_arg_macro!(/**/); //~ ERROR unexpected end - | ^^^^^^^^^^^^^^^^^^^^^ +LL | / macro_rules! one_arg_macro { +LL | | ($fmt:expr) => (print!(concat!($fmt, "/n"))); +LL | | } + | |_- when calling this macro +... +LL | one_arg_macro!(/**/); //~ ERROR unexpected end + | ^^^^^^^^^^^^^^^^^^^^^ unexpected end of macro invocation error: aborting due to previous error diff --git a/src/test/ui/fail-simple.stderr b/src/test/ui/fail-simple.stderr index 764f2c464bcb8..4a4aec5b6ac57 100644 --- a/src/test/ui/fail-simple.stderr +++ b/src/test/ui/fail-simple.stderr @@ -2,7 +2,7 @@ error: no rules expected the token `@` --> $DIR/fail-simple.rs:12:12 | LL | panic!(@); //~ ERROR no rules expected the token `@` - | ^ + | ^ no rules expected the token `@` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-7970a.stderr b/src/test/ui/issues/issue-7970a.stderr index 7ad95717185b8..94beebf514e17 100644 --- a/src/test/ui/issues/issue-7970a.stderr +++ b/src/test/ui/issues/issue-7970a.stderr @@ -1,8 +1,13 @@ error: unexpected end of macro invocation --> $DIR/issue-7970a.rs:16:5 | -LL | one_arg_macro!(); - | ^^^^^^^^^^^^^^^^^ +LL | / macro_rules! one_arg_macro { +LL | | ($fmt:expr) => (print!(concat!($fmt, "/n"))); +LL | | } + | |_- when calling this macro +... +LL | one_arg_macro!(); + | ^^^^^^^^^^^^^^^^^ unexpected end of macro invocation error: aborting due to previous error diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr index 22f1c94fced6f..6f77eb634399b 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr +++ b/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr @@ -51,20 +51,41 @@ LL | ($(a)?*) => {} error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:41:11 | -LL | foo!(a?); //~ ERROR no rules expected the token `?` - | ^ +LL | / macro_rules! foo { +LL | | ($(a)?) => {} +LL | | //~^ERROR using the `?` macro Kleene operator for +LL | | //~|ERROR expected `*` or `+` +LL | | } + | |_- when calling this macro +... +LL | foo!(a?); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:42:11 | -LL | foo!(a?a); //~ ERROR no rules expected the token `?` - | ^ +LL | / macro_rules! foo { +LL | | ($(a)?) => {} +LL | | //~^ERROR using the `?` macro Kleene operator for +LL | | //~|ERROR expected `*` or `+` +LL | | } + | |_- when calling this macro +... +LL | foo!(a?a); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:43:11 | -LL | foo!(a?a?a); //~ ERROR no rules expected the token `?` - | ^ +LL | / macro_rules! foo { +LL | | ($(a)?) => {} +LL | | //~^ERROR using the `?` macro Kleene operator for +LL | | //~|ERROR expected `*` or `+` +LL | | } + | |_- when calling this macro +... +LL | foo!(a?a?a); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: aborting due to 10 previous errors diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr index 0a15bdb10686d..3bdfae5ccdf7f 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr +++ b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr @@ -7,68 +7,123 @@ LL | ($(a),?) => {} //~ERROR the `?` macro repetition operator error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:36:11 | -LL | foo!(a?); //~ ERROR no rules expected the token `?` - | ^ +LL | / macro_rules! foo { +LL | | ($(a)?) => {} +LL | | } + | |_- when calling this macro +... +LL | foo!(a?); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:37:11 | -LL | foo!(a?a); //~ ERROR no rules expected the token `?` - | ^ +LL | / macro_rules! foo { +LL | | ($(a)?) => {} +LL | | } + | |_- when calling this macro +... +LL | foo!(a?a); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:38:11 | -LL | foo!(a?a?a); //~ ERROR no rules expected the token `?` - | ^ +LL | / macro_rules! foo { +LL | | ($(a)?) => {} +LL | | } + | |_- when calling this macro +... +LL | foo!(a?a?a); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: unexpected end of macro invocation --> $DIR/macro-at-most-once-rep-2018.rs:40:5 | -LL | barplus!(); //~ERROR unexpected end of macro invocation - | ^^^^^^^^^^^ +LL | / macro_rules! barplus { +LL | | ($(a)?+) => {} // ok. matches "a+" and "+" +LL | | } + | |_- when calling this macro +... +LL | barplus!(); //~ERROR unexpected end of macro invocation + | ^^^^^^^^^^^ unexpected end of macro invocation error: unexpected end of macro invocation --> $DIR/macro-at-most-once-rep-2018.rs:41:14 | -LL | barplus!(a); //~ERROR unexpected end of macro invocation - | ^ +LL | / macro_rules! barplus { +LL | | ($(a)?+) => {} // ok. matches "a+" and "+" +LL | | } + | |_- when calling this macro +... +LL | barplus!(a); //~ERROR unexpected end of macro invocation + | ^ unexpected end of macro invocation error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:42:15 | -LL | barplus!(a?); //~ ERROR no rules expected the token `?` - | ^ +LL | / macro_rules! barplus { +LL | | ($(a)?+) => {} // ok. matches "a+" and "+" +LL | | } + | |_- when calling this macro +... +LL | barplus!(a?); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:43:15 | -LL | barplus!(a?a); //~ ERROR no rules expected the token `?` - | ^ +LL | / macro_rules! barplus { +LL | | ($(a)?+) => {} // ok. matches "a+" and "+" +LL | | } + | |_- when calling this macro +... +LL | barplus!(a?a); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: unexpected end of macro invocation --> $DIR/macro-at-most-once-rep-2018.rs:47:5 | -LL | barstar!(); //~ERROR unexpected end of macro invocation - | ^^^^^^^^^^^ +LL | / macro_rules! barstar { +LL | | ($(a)?*) => {} // ok. matches "a*" and "*" +LL | | } + | |_- when calling this macro +... +LL | barstar!(); //~ERROR unexpected end of macro invocation + | ^^^^^^^^^^^ unexpected end of macro invocation error: unexpected end of macro invocation --> $DIR/macro-at-most-once-rep-2018.rs:48:14 | -LL | barstar!(a); //~ERROR unexpected end of macro invocation - | ^ +LL | / macro_rules! barstar { +LL | | ($(a)?*) => {} // ok. matches "a*" and "*" +LL | | } + | |_- when calling this macro +... +LL | barstar!(a); //~ERROR unexpected end of macro invocation + | ^ unexpected end of macro invocation error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:49:15 | -LL | barstar!(a?); //~ ERROR no rules expected the token `?` - | ^ +LL | / macro_rules! barstar { +LL | | ($(a)?*) => {} // ok. matches "a*" and "*" +LL | | } + | |_- when calling this macro +... +LL | barstar!(a?); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:50:15 | -LL | barstar!(a?a); //~ ERROR no rules expected the token `?` - | ^ +LL | / macro_rules! barstar { +LL | | ($(a)?*) => {} // ok. matches "a*" and "*" +LL | | } + | |_- when calling this macro +... +LL | barstar!(a?a); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: aborting due to 12 previous errors diff --git a/src/test/ui/macros/macro-non-lifetime.stderr b/src/test/ui/macros/macro-non-lifetime.stderr index 93b7f481842ac..48a93010c3b6f 100644 --- a/src/test/ui/macros/macro-non-lifetime.stderr +++ b/src/test/ui/macros/macro-non-lifetime.stderr @@ -1,8 +1,11 @@ error: no rules expected the token `a` --> $DIR/macro-non-lifetime.rs:18:8 | +LL | macro_rules! m { ($x:lifetime) => { } } + | --------------------------------------- when calling this macro +... LL | m!(a); - | ^ + | ^ no rules expected the token `a` error: aborting due to previous error diff --git a/src/test/ui/macros/missing-comma.stderr b/src/test/ui/macros/missing-comma.stderr index 9d8de87e5bb7f..5548be86a1300 100644 --- a/src/test/ui/macros/missing-comma.stderr +++ b/src/test/ui/macros/missing-comma.stderr @@ -7,32 +7,68 @@ LL | println!("{}" a); error: no rules expected the token `b` --> $DIR/missing-comma.rs:22:12 | -LL | foo!(a b); - | -^ - | | - | help: missing comma here +LL | / macro_rules! foo { +LL | | ($a:ident) => (); +LL | | ($a:ident, $b:ident) => (); +LL | | ($a:ident, $b:ident, $c:ident) => (); +LL | | ($a:ident, $b:ident, $c:ident, $d:ident) => (); +LL | | ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => (); +LL | | } + | |_- when calling this macro +... +LL | foo!(a b); + | -^ no rules expected the token `b` + | | + | help: missing comma here error: no rules expected the token `e` --> $DIR/missing-comma.rs:24:21 | -LL | foo!(a, b, c, d e); - | -^ - | | - | help: missing comma here +LL | / macro_rules! foo { +LL | | ($a:ident) => (); +LL | | ($a:ident, $b:ident) => (); +LL | | ($a:ident, $b:ident, $c:ident) => (); +LL | | ($a:ident, $b:ident, $c:ident, $d:ident) => (); +LL | | ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => (); +LL | | } + | |_- when calling this macro +... +LL | foo!(a, b, c, d e); + | -^ no rules expected the token `e` + | | + | help: missing comma here error: no rules expected the token `d` --> $DIR/missing-comma.rs:26:18 | -LL | foo!(a, b, c d, e); - | -^ - | | - | help: missing comma here +LL | / macro_rules! foo { +LL | | ($a:ident) => (); +LL | | ($a:ident, $b:ident) => (); +LL | | ($a:ident, $b:ident, $c:ident) => (); +LL | | ($a:ident, $b:ident, $c:ident, $d:ident) => (); +LL | | ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => (); +LL | | } + | |_- when calling this macro +... +LL | foo!(a, b, c d, e); + | -^ no rules expected the token `d` + | | + | help: missing comma here error: no rules expected the token `d` --> $DIR/missing-comma.rs:28:18 | -LL | foo!(a, b, c d e); - | ^ +LL | / macro_rules! foo { +LL | | ($a:ident) => (); +LL | | ($a:ident, $b:ident) => (); +LL | | ($a:ident, $b:ident, $c:ident) => (); +LL | | ($a:ident, $b:ident, $c:ident, $d:ident) => (); +LL | | ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => (); +LL | | } + | |_- when calling this macro +... +LL | foo!(a, b, c d e); + | ^ no rules expected the token `d` error: aborting due to 5 previous errors diff --git a/src/test/ui/macros/nonterminal-matching.stderr b/src/test/ui/macros/nonterminal-matching.stderr index bf2221d52a492..23853978d371b 100644 --- a/src/test/ui/macros/nonterminal-matching.stderr +++ b/src/test/ui/macros/nonterminal-matching.stderr @@ -2,7 +2,7 @@ error: no rules expected the token `enum E { }` --> $DIR/nonterminal-matching.rs:29:10 | LL | n!(a $nt_item b); //~ ERROR no rules expected the token `enum E { }` - | ^^^^^^^^ + | ^^^^^^^^ no rules expected the token `enum E { }` ... LL | complex_nonterminal!(enum E {}); | -------------------------------- in this macro invocation diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr index a9ffef8ef8090..ecc3694d120fa 100644 --- a/src/test/ui/macros/trace_faulty_macros.stderr +++ b/src/test/ui/macros/trace_faulty_macros.stderr @@ -1,11 +1,16 @@ error: no rules expected the token `bcd` --> $DIR/trace_faulty_macros.rs:17:26 | -LL | my_faulty_macro!(bcd); //~ ERROR no rules - | ^^^ +LL | / macro_rules! my_faulty_macro { +LL | | () => { +LL | | my_faulty_macro!(bcd); //~ ERROR no rules + | | ^^^ no rules expected the token `bcd` +LL | | }; +LL | | } + | |_- when calling this macro ... -LL | my_faulty_macro!(); - | ------------------- in this macro invocation +LL | my_faulty_macro!(); + | ------------------- in this macro invocation note: trace_macro --> $DIR/trace_faulty_macros.rs:43:5 diff --git a/src/test/ui/parser/macro/macro-doc-comments-1.stderr b/src/test/ui/parser/macro/macro-doc-comments-1.stderr index a7fdd28b0cab8..4fcc56ac832eb 100644 --- a/src/test/ui/parser/macro/macro-doc-comments-1.stderr +++ b/src/test/ui/parser/macro/macro-doc-comments-1.stderr @@ -1,8 +1,13 @@ error: no rules expected the token `!` --> $DIR/macro-doc-comments-1.rs:16:5 | -LL | //! Inner - | ^^^^^^^^^ +LL | / macro_rules! outer { +LL | | (#[$outer:meta]) => () +LL | | } + | |_- when calling this macro +... +LL | //! Inner + | ^^^^^^^^^ no rules expected the token `!` error: aborting due to previous error diff --git a/src/test/ui/parser/macro/macro-doc-comments-2.stderr b/src/test/ui/parser/macro/macro-doc-comments-2.stderr index bae9823b9b2fa..b34e99fbd9e77 100644 --- a/src/test/ui/parser/macro/macro-doc-comments-2.stderr +++ b/src/test/ui/parser/macro/macro-doc-comments-2.stderr @@ -1,8 +1,13 @@ error: no rules expected the token `[` --> $DIR/macro-doc-comments-2.rs:16:5 | -LL | /// Outer - | ^ +LL | / macro_rules! inner { +LL | | (#![$inner:meta]) => () +LL | | } + | |_- when calling this macro +... +LL | /// Outer + | ^ no rules expected the token `[` error: aborting due to previous error diff --git a/src/test/ui/underscore-ident-matcher.stderr b/src/test/ui/underscore-ident-matcher.stderr index 7f2b6ac30b0da..19d489db5723f 100644 --- a/src/test/ui/underscore-ident-matcher.stderr +++ b/src/test/ui/underscore-ident-matcher.stderr @@ -1,8 +1,15 @@ error: no rules expected the token `_` --> $DIR/underscore-ident-matcher.rs:18:19 | -LL | let identity!(_) = 10; //~ ERROR no rules expected the token `_` - | ^ +LL | / macro_rules! identity { +LL | | ($i: ident) => ( +LL | | $i +LL | | ) +LL | | } + | |_- when calling this macro +... +LL | let identity!(_) = 10; //~ ERROR no rules expected the token `_` + | ^ no rules expected the token `_` error: aborting due to previous error diff --git a/src/test/ui/vec/vec-macro-with-comma-only.stderr b/src/test/ui/vec/vec-macro-with-comma-only.stderr index f5341ccc31286..856d85ef5cdaa 100644 --- a/src/test/ui/vec/vec-macro-with-comma-only.stderr +++ b/src/test/ui/vec/vec-macro-with-comma-only.stderr @@ -2,7 +2,7 @@ error: no rules expected the token `,` --> $DIR/vec-macro-with-comma-only.rs:12:10 | LL | vec![,]; //~ ERROR no rules expected the token `,` - | ^ + | ^ no rules expected the token `,` error: aborting due to previous error From 1ab45ec7e366f6f16a6a3d0a58cacb0ee48ef406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 24 Oct 2018 11:34:23 -0700 Subject: [PATCH 2/2] Point to macro def span instead of whole body --- src/libsyntax/ext/tt/macro_rules.rs | 2 +- src/test/ui/empty/empty-comment.stderr | 10 +- src/test/ui/issues/issue-7970a.stderr | 10 +- ...-at-most-once-rep-2018-feature-gate.stderr | 36 ++---- .../macros/macro-at-most-once-rep-2018.stderr | 110 +++++++----------- src/test/ui/macros/macro-non-lifetime.stderr | 2 +- src/test/ui/macros/missing-comma.stderr | 68 ++++------- src/test/ui/macros/trace_faulty_macros.stderr | 16 ++- .../parser/macro/macro-doc-comments-1.stderr | 10 +- .../parser/macro/macro-doc-comments-2.stderr | 10 +- src/test/ui/underscore-ident-matcher.stderr | 12 +- 11 files changed, 107 insertions(+), 179 deletions(-) diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 41e8cbe550211..03fb89b21a43c 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -187,7 +187,7 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt, err.span_label(span, best_fail_msg); if let Some(sp) = def_span { if cx.source_map().span_to_filename(sp).is_real() && !sp.is_dummy() { - err.span_label(sp, "when calling this macro"); + err.span_label(cx.source_map().def_span(sp), "when calling this macro"); } } diff --git a/src/test/ui/empty/empty-comment.stderr b/src/test/ui/empty/empty-comment.stderr index e15f347f49d9c..de826102081e7 100644 --- a/src/test/ui/empty/empty-comment.stderr +++ b/src/test/ui/empty/empty-comment.stderr @@ -1,13 +1,11 @@ error: unexpected end of macro invocation --> $DIR/empty-comment.rs:20:5 | -LL | / macro_rules! one_arg_macro { -LL | | ($fmt:expr) => (print!(concat!($fmt, "/n"))); -LL | | } - | |_- when calling this macro +LL | macro_rules! one_arg_macro { + | -------------------------- when calling this macro ... -LL | one_arg_macro!(/**/); //~ ERROR unexpected end - | ^^^^^^^^^^^^^^^^^^^^^ unexpected end of macro invocation +LL | one_arg_macro!(/**/); //~ ERROR unexpected end + | ^^^^^^^^^^^^^^^^^^^^^ unexpected end of macro invocation error: aborting due to previous error diff --git a/src/test/ui/issues/issue-7970a.stderr b/src/test/ui/issues/issue-7970a.stderr index 94beebf514e17..96fb374b58c6c 100644 --- a/src/test/ui/issues/issue-7970a.stderr +++ b/src/test/ui/issues/issue-7970a.stderr @@ -1,13 +1,11 @@ error: unexpected end of macro invocation --> $DIR/issue-7970a.rs:16:5 | -LL | / macro_rules! one_arg_macro { -LL | | ($fmt:expr) => (print!(concat!($fmt, "/n"))); -LL | | } - | |_- when calling this macro +LL | macro_rules! one_arg_macro { + | -------------------------- when calling this macro ... -LL | one_arg_macro!(); - | ^^^^^^^^^^^^^^^^^ unexpected end of macro invocation +LL | one_arg_macro!(); + | ^^^^^^^^^^^^^^^^^ unexpected end of macro invocation error: aborting due to previous error diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr index 6f77eb634399b..7705ba3b11ed5 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr +++ b/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr @@ -51,41 +51,29 @@ LL | ($(a)?*) => {} error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:41:11 | -LL | / macro_rules! foo { -LL | | ($(a)?) => {} -LL | | //~^ERROR using the `?` macro Kleene operator for -LL | | //~|ERROR expected `*` or `+` -LL | | } - | |_- when calling this macro +LL | macro_rules! foo { + | ---------------- when calling this macro ... -LL | foo!(a?); //~ ERROR no rules expected the token `?` - | ^ no rules expected the token `?` +LL | foo!(a?); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:42:11 | -LL | / macro_rules! foo { -LL | | ($(a)?) => {} -LL | | //~^ERROR using the `?` macro Kleene operator for -LL | | //~|ERROR expected `*` or `+` -LL | | } - | |_- when calling this macro +LL | macro_rules! foo { + | ---------------- when calling this macro ... -LL | foo!(a?a); //~ ERROR no rules expected the token `?` - | ^ no rules expected the token `?` +LL | foo!(a?a); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018-feature-gate.rs:43:11 | -LL | / macro_rules! foo { -LL | | ($(a)?) => {} -LL | | //~^ERROR using the `?` macro Kleene operator for -LL | | //~|ERROR expected `*` or `+` -LL | | } - | |_- when calling this macro +LL | macro_rules! foo { + | ---------------- when calling this macro ... -LL | foo!(a?a?a); //~ ERROR no rules expected the token `?` - | ^ no rules expected the token `?` +LL | foo!(a?a?a); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: aborting due to 10 previous errors diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr index 3bdfae5ccdf7f..25dd66b81f567 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2018.stderr +++ b/src/test/ui/macros/macro-at-most-once-rep-2018.stderr @@ -7,123 +7,101 @@ LL | ($(a),?) => {} //~ERROR the `?` macro repetition operator error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:36:11 | -LL | / macro_rules! foo { -LL | | ($(a)?) => {} -LL | | } - | |_- when calling this macro +LL | macro_rules! foo { + | ---------------- when calling this macro ... -LL | foo!(a?); //~ ERROR no rules expected the token `?` - | ^ no rules expected the token `?` +LL | foo!(a?); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:37:11 | -LL | / macro_rules! foo { -LL | | ($(a)?) => {} -LL | | } - | |_- when calling this macro +LL | macro_rules! foo { + | ---------------- when calling this macro ... -LL | foo!(a?a); //~ ERROR no rules expected the token `?` - | ^ no rules expected the token `?` +LL | foo!(a?a); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:38:11 | -LL | / macro_rules! foo { -LL | | ($(a)?) => {} -LL | | } - | |_- when calling this macro +LL | macro_rules! foo { + | ---------------- when calling this macro ... -LL | foo!(a?a?a); //~ ERROR no rules expected the token `?` - | ^ no rules expected the token `?` +LL | foo!(a?a?a); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: unexpected end of macro invocation --> $DIR/macro-at-most-once-rep-2018.rs:40:5 | -LL | / macro_rules! barplus { -LL | | ($(a)?+) => {} // ok. matches "a+" and "+" -LL | | } - | |_- when calling this macro +LL | macro_rules! barplus { + | -------------------- when calling this macro ... -LL | barplus!(); //~ERROR unexpected end of macro invocation - | ^^^^^^^^^^^ unexpected end of macro invocation +LL | barplus!(); //~ERROR unexpected end of macro invocation + | ^^^^^^^^^^^ unexpected end of macro invocation error: unexpected end of macro invocation --> $DIR/macro-at-most-once-rep-2018.rs:41:14 | -LL | / macro_rules! barplus { -LL | | ($(a)?+) => {} // ok. matches "a+" and "+" -LL | | } - | |_- when calling this macro +LL | macro_rules! barplus { + | -------------------- when calling this macro ... -LL | barplus!(a); //~ERROR unexpected end of macro invocation - | ^ unexpected end of macro invocation +LL | barplus!(a); //~ERROR unexpected end of macro invocation + | ^ unexpected end of macro invocation error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:42:15 | -LL | / macro_rules! barplus { -LL | | ($(a)?+) => {} // ok. matches "a+" and "+" -LL | | } - | |_- when calling this macro +LL | macro_rules! barplus { + | -------------------- when calling this macro ... -LL | barplus!(a?); //~ ERROR no rules expected the token `?` - | ^ no rules expected the token `?` +LL | barplus!(a?); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:43:15 | -LL | / macro_rules! barplus { -LL | | ($(a)?+) => {} // ok. matches "a+" and "+" -LL | | } - | |_- when calling this macro +LL | macro_rules! barplus { + | -------------------- when calling this macro ... -LL | barplus!(a?a); //~ ERROR no rules expected the token `?` - | ^ no rules expected the token `?` +LL | barplus!(a?a); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: unexpected end of macro invocation --> $DIR/macro-at-most-once-rep-2018.rs:47:5 | -LL | / macro_rules! barstar { -LL | | ($(a)?*) => {} // ok. matches "a*" and "*" -LL | | } - | |_- when calling this macro +LL | macro_rules! barstar { + | -------------------- when calling this macro ... -LL | barstar!(); //~ERROR unexpected end of macro invocation - | ^^^^^^^^^^^ unexpected end of macro invocation +LL | barstar!(); //~ERROR unexpected end of macro invocation + | ^^^^^^^^^^^ unexpected end of macro invocation error: unexpected end of macro invocation --> $DIR/macro-at-most-once-rep-2018.rs:48:14 | -LL | / macro_rules! barstar { -LL | | ($(a)?*) => {} // ok. matches "a*" and "*" -LL | | } - | |_- when calling this macro +LL | macro_rules! barstar { + | -------------------- when calling this macro ... -LL | barstar!(a); //~ERROR unexpected end of macro invocation - | ^ unexpected end of macro invocation +LL | barstar!(a); //~ERROR unexpected end of macro invocation + | ^ unexpected end of macro invocation error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:49:15 | -LL | / macro_rules! barstar { -LL | | ($(a)?*) => {} // ok. matches "a*" and "*" -LL | | } - | |_- when calling this macro +LL | macro_rules! barstar { + | -------------------- when calling this macro ... -LL | barstar!(a?); //~ ERROR no rules expected the token `?` - | ^ no rules expected the token `?` +LL | barstar!(a?); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: no rules expected the token `?` --> $DIR/macro-at-most-once-rep-2018.rs:50:15 | -LL | / macro_rules! barstar { -LL | | ($(a)?*) => {} // ok. matches "a*" and "*" -LL | | } - | |_- when calling this macro +LL | macro_rules! barstar { + | -------------------- when calling this macro ... -LL | barstar!(a?a); //~ ERROR no rules expected the token `?` - | ^ no rules expected the token `?` +LL | barstar!(a?a); //~ ERROR no rules expected the token `?` + | ^ no rules expected the token `?` error: aborting due to 12 previous errors diff --git a/src/test/ui/macros/macro-non-lifetime.stderr b/src/test/ui/macros/macro-non-lifetime.stderr index 48a93010c3b6f..d526023d441b1 100644 --- a/src/test/ui/macros/macro-non-lifetime.stderr +++ b/src/test/ui/macros/macro-non-lifetime.stderr @@ -2,7 +2,7 @@ error: no rules expected the token `a` --> $DIR/macro-non-lifetime.rs:18:8 | LL | macro_rules! m { ($x:lifetime) => { } } - | --------------------------------------- when calling this macro + | -------------- when calling this macro ... LL | m!(a); | ^ no rules expected the token `a` diff --git a/src/test/ui/macros/missing-comma.stderr b/src/test/ui/macros/missing-comma.stderr index 5548be86a1300..1d6af44bd08a5 100644 --- a/src/test/ui/macros/missing-comma.stderr +++ b/src/test/ui/macros/missing-comma.stderr @@ -7,68 +7,44 @@ LL | println!("{}" a); error: no rules expected the token `b` --> $DIR/missing-comma.rs:22:12 | -LL | / macro_rules! foo { -LL | | ($a:ident) => (); -LL | | ($a:ident, $b:ident) => (); -LL | | ($a:ident, $b:ident, $c:ident) => (); -LL | | ($a:ident, $b:ident, $c:ident, $d:ident) => (); -LL | | ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => (); -LL | | } - | |_- when calling this macro +LL | macro_rules! foo { + | ---------------- when calling this macro ... -LL | foo!(a b); - | -^ no rules expected the token `b` - | | - | help: missing comma here +LL | foo!(a b); + | -^ no rules expected the token `b` + | | + | help: missing comma here error: no rules expected the token `e` --> $DIR/missing-comma.rs:24:21 | -LL | / macro_rules! foo { -LL | | ($a:ident) => (); -LL | | ($a:ident, $b:ident) => (); -LL | | ($a:ident, $b:ident, $c:ident) => (); -LL | | ($a:ident, $b:ident, $c:ident, $d:ident) => (); -LL | | ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => (); -LL | | } - | |_- when calling this macro +LL | macro_rules! foo { + | ---------------- when calling this macro ... -LL | foo!(a, b, c, d e); - | -^ no rules expected the token `e` - | | - | help: missing comma here +LL | foo!(a, b, c, d e); + | -^ no rules expected the token `e` + | | + | help: missing comma here error: no rules expected the token `d` --> $DIR/missing-comma.rs:26:18 | -LL | / macro_rules! foo { -LL | | ($a:ident) => (); -LL | | ($a:ident, $b:ident) => (); -LL | | ($a:ident, $b:ident, $c:ident) => (); -LL | | ($a:ident, $b:ident, $c:ident, $d:ident) => (); -LL | | ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => (); -LL | | } - | |_- when calling this macro +LL | macro_rules! foo { + | ---------------- when calling this macro ... -LL | foo!(a, b, c d, e); - | -^ no rules expected the token `d` - | | - | help: missing comma here +LL | foo!(a, b, c d, e); + | -^ no rules expected the token `d` + | | + | help: missing comma here error: no rules expected the token `d` --> $DIR/missing-comma.rs:28:18 | -LL | / macro_rules! foo { -LL | | ($a:ident) => (); -LL | | ($a:ident, $b:ident) => (); -LL | | ($a:ident, $b:ident, $c:ident) => (); -LL | | ($a:ident, $b:ident, $c:ident, $d:ident) => (); -LL | | ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => (); -LL | | } - | |_- when calling this macro +LL | macro_rules! foo { + | ---------------- when calling this macro ... -LL | foo!(a, b, c d e); - | ^ no rules expected the token `d` +LL | foo!(a, b, c d e); + | ^ no rules expected the token `d` error: aborting due to 5 previous errors diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr index ecc3694d120fa..853eb5847c0cd 100644 --- a/src/test/ui/macros/trace_faulty_macros.stderr +++ b/src/test/ui/macros/trace_faulty_macros.stderr @@ -1,16 +1,14 @@ error: no rules expected the token `bcd` --> $DIR/trace_faulty_macros.rs:17:26 | -LL | / macro_rules! my_faulty_macro { -LL | | () => { -LL | | my_faulty_macro!(bcd); //~ ERROR no rules - | | ^^^ no rules expected the token `bcd` -LL | | }; -LL | | } - | |_- when calling this macro +LL | macro_rules! my_faulty_macro { + | ---------------------------- when calling this macro +LL | () => { +LL | my_faulty_macro!(bcd); //~ ERROR no rules + | ^^^ no rules expected the token `bcd` ... -LL | my_faulty_macro!(); - | ------------------- in this macro invocation +LL | my_faulty_macro!(); + | ------------------- in this macro invocation note: trace_macro --> $DIR/trace_faulty_macros.rs:43:5 diff --git a/src/test/ui/parser/macro/macro-doc-comments-1.stderr b/src/test/ui/parser/macro/macro-doc-comments-1.stderr index 4fcc56ac832eb..1e765dcde4f68 100644 --- a/src/test/ui/parser/macro/macro-doc-comments-1.stderr +++ b/src/test/ui/parser/macro/macro-doc-comments-1.stderr @@ -1,13 +1,11 @@ error: no rules expected the token `!` --> $DIR/macro-doc-comments-1.rs:16:5 | -LL | / macro_rules! outer { -LL | | (#[$outer:meta]) => () -LL | | } - | |_- when calling this macro +LL | macro_rules! outer { + | ------------------ when calling this macro ... -LL | //! Inner - | ^^^^^^^^^ no rules expected the token `!` +LL | //! Inner + | ^^^^^^^^^ no rules expected the token `!` error: aborting due to previous error diff --git a/src/test/ui/parser/macro/macro-doc-comments-2.stderr b/src/test/ui/parser/macro/macro-doc-comments-2.stderr index b34e99fbd9e77..0ab8a3cafb55f 100644 --- a/src/test/ui/parser/macro/macro-doc-comments-2.stderr +++ b/src/test/ui/parser/macro/macro-doc-comments-2.stderr @@ -1,13 +1,11 @@ error: no rules expected the token `[` --> $DIR/macro-doc-comments-2.rs:16:5 | -LL | / macro_rules! inner { -LL | | (#![$inner:meta]) => () -LL | | } - | |_- when calling this macro +LL | macro_rules! inner { + | ------------------ when calling this macro ... -LL | /// Outer - | ^ no rules expected the token `[` +LL | /// Outer + | ^ no rules expected the token `[` error: aborting due to previous error diff --git a/src/test/ui/underscore-ident-matcher.stderr b/src/test/ui/underscore-ident-matcher.stderr index 19d489db5723f..e148c48ed1314 100644 --- a/src/test/ui/underscore-ident-matcher.stderr +++ b/src/test/ui/underscore-ident-matcher.stderr @@ -1,15 +1,11 @@ error: no rules expected the token `_` --> $DIR/underscore-ident-matcher.rs:18:19 | -LL | / macro_rules! identity { -LL | | ($i: ident) => ( -LL | | $i -LL | | ) -LL | | } - | |_- when calling this macro +LL | macro_rules! identity { + | --------------------- when calling this macro ... -LL | let identity!(_) = 10; //~ ERROR no rules expected the token `_` - | ^ no rules expected the token `_` +LL | let identity!(_) = 10; //~ ERROR no rules expected the token `_` + | ^ no rules expected the token `_` error: aborting due to previous error