diff options
| author | kennytm <kennytm@gmail.com> | 2018-10-26 18:25:05 +0800 |
|---|---|---|
| committer | kennytm <kennytm@gmail.com> | 2018-10-26 23:06:30 +0800 |
| commit | eb74711b5444a10a7a10570a3c206ccee656850e (patch) | |
| tree | 4e474a592c81e2a80eebe5d2a5e15b78106530cf /src/libsyntax/ext | |
| parent | c6cd57dd860efbe0cb7506dfad93462bcb520d74 (diff) | |
| parent | 1ab45ec7e366f6f16a6a3d0a58cacb0ee48ef406 (diff) | |
| download | rust-eb74711b5444a10a7a10570a3c206ccee656850e.tar.gz rust-eb74711b5444a10a7a10570a3c206ccee656850e.zip | |
Rollup merge of #55298 - estebank:macro-def, r=pnkfelix
Point at macro definition when no rules expect token Fix #35150.
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 25 |
3 files changed, 39 insertions, 13 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 5bf1a7dd663..1701c8da2c5 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -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 = @@ -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 { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 4deeb4a43d9..33b651e1b38 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 5e53b8b99c7..543dc478d7b 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -79,16 +79,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, @@ -104,6 +107,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], @@ -183,7 +187,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(cx.source_map().def_span(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() { @@ -194,7 +205,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( |
