Skip to content

Commit

Permalink
Point at macro definition when no rules expect token
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Oct 24, 2018
1 parent a66dc8a commit 8227a93
Show file tree
Hide file tree
Showing 21 changed files with 256 additions and 82 deletions.
18 changes: 14 additions & 4 deletions src/libsyntax/ext/base.rs
Expand Up @@ -247,8 +247,13 @@ impl<F> 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<dyn MacResult+'cx>;
fn expand<'cx>(
&self,
ecx: &'cx mut ExtCtxt,
span: Span,
input: TokenStream,
def_span: Option<Span>,
) -> Box<dyn MacResult+'cx>;
}

pub type MacroExpanderFn =
Expand All @@ -259,8 +264,13 @@ impl<F> TTMacroExpander for F
where F: for<'cx> Fn(&'cx mut ExtCtxt, Span, &[tokenstream::TokenTree])
-> Box<dyn MacResult+'cx>
{
fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt, span: Span, input: TokenStream)
-> Box<dyn MacResult+'cx> {
fn expand<'cx>(
&self,
ecx: &'cx mut ExtCtxt,
span: Span,
input: TokenStream,
_def_span: Option<Span>,
) -> Box<dyn MacResult+'cx> {
struct AvoidInterpolatedIdents;

impl Folder for AvoidInterpolatedIdents {
Expand Down
9 changes: 7 additions & 2 deletions src/libsyntax/ext/expand.rs
Expand Up @@ -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))
}
}

Expand All @@ -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),
))
}
}

Expand Down
25 changes: 18 additions & 7 deletions src/libsyntax/ext/tt/macro_rules.rs
Expand Up @@ -74,16 +74,19 @@ struct MacroRulesMacroExpander {
}

impl TTMacroExpander for MacroRulesMacroExpander {
fn expand<'cx>(&self,
cx: &'cx mut ExtCtxt,
sp: Span,
input: TokenStream)
-> Box<dyn MacResult+'cx> {
fn expand<'cx>(
&self,
cx: &'cx mut ExtCtxt,
sp: Span,
input: TokenStream,
def_span: Option<Span>,
) -> Box<dyn MacResult+'cx> {
if !self.valid {
return DummyResult::any(sp);
}
generic_extension(cx,
sp,
def_span,
self.name,
input,
&self.lhses,
Expand All @@ -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<Span>,
name: ast::Ident,
arg: TokenStream,
lhses: &[quoted::TokenTree],
Expand Down Expand Up @@ -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() {
Expand All @@ -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(
Expand Down
3 changes: 2 additions & 1 deletion src/test/run-pass-fulldeps/auxiliary/plugin_args.rs
Expand Up @@ -38,7 +38,8 @@ impl TTMacroExpander for Expander {
fn expand<'cx>(&self,
ecx: &'cx mut ExtCtxt,
sp: Span,
_: TokenStream) -> Box<MacResult+'cx> {
_: TokenStream,
_: Option<Span>) -> Box<MacResult+'cx> {
let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i))
.collect::<Vec<_>>().join(", ");
MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args)))
Expand Down
Expand Up @@ -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

Expand Up @@ -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

Expand Up @@ -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 `<eof>`
--> <::edition_kw_macro_2015::passes_ident macros>:1:22
Expand Down
Expand Up @@ -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 `<eof>`
--> <::edition_kw_macro_2018::passes_ident macros>:1:22
Expand Down
9 changes: 7 additions & 2 deletions 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

2 changes: 1 addition & 1 deletion src/test/ui/fail-simple.stderr
Expand Up @@ -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

9 changes: 7 additions & 2 deletions 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

33 changes: 27 additions & 6 deletions src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.stderr
Expand Up @@ -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

Expand Down

0 comments on commit 8227a93

Please sign in to comment.