Keep label on moved spans and point at macro invocation on parse error

This commit is contained in:
Esteban Küber 2018-11-05 16:27:28 -08:00
parent 76449d86c0
commit c45871ba02
7 changed files with 40 additions and 15 deletions

View File

@ -139,6 +139,17 @@ impl Diagnostic {
self
}
pub fn replace_span_with(&mut self, after: Span) -> &mut Self {
let before = self.span.clone();
self.set_span(after);
for span_label in before.span_labels() {
if let Some(label) = span_label.label {
self.span_label(after, label);
}
}
self
}
pub fn note_expected_found(&mut self,
label: &dyn fmt::Display,
expected: DiagnosticStyledString,

View File

@ -53,20 +53,24 @@ impl<'a> ParserAnyMacro<'a> {
pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
let fragment = panictry!(parser.parse_ast_fragment(kind, true).map_err(|mut e| {
if e.span.is_dummy() { // Get around lack of span in error (#30128)
e.set_span(site_span);
e.span_label(site_span, "in this macro expansion");
e.span_label(arm_span, "in this macro arm");
} else if parser.token == token::Eof { // (#52866)
e.set_span(parser.sess.source_map().next_point(parser.span));
}
if parser.token == token::Eof {
if parser.token == token::Eof && e.message().ends_with(", found `<eof>`") {
if !e.span.is_dummy() { // early end of macro arm (#52866)
e.replace_span_with(parser.sess.source_map().next_point(parser.span));
}
let msg = &e.message[0];
e.message[0] = (
msg.0.replace(", found `<eof>`", ", found the end of the macro arm"),
msg.1,
);
}
if e.span.is_dummy() { // Get around lack of span in error (#30128)
e.replace_span_with(site_span);
if parser.sess.source_map().span_to_filename(arm_span).is_real() {
e.span_label(arm_span, "in this macro arm");
}
} else if !parser.sess.source_map().span_to_filename(parser.span).is_real() {
e.span_label(site_span, "in this macro invocation");
}
e
}));

View File

@ -12,7 +12,6 @@
macro_rules! mod_decl {
($i:ident) => { mod $i; }
//~^ ERROR Cannot declare a non-inline module inside a block
}
mod macro_expanded_mod_helper {
@ -21,4 +20,5 @@ mod macro_expanded_mod_helper {
fn main() {
mod_decl!(foo);
//~^ ERROR Cannot declare a non-inline module inside a block
}

View File

@ -1,8 +1,8 @@
error: Cannot declare a non-inline module inside a block unless it has a path attribute
--> $DIR/macro-expanded-mod.rs:14:28
--> $DIR/macro-expanded-mod.rs:22:15
|
LL | ($i:ident) => { mod $i; }
| ^
LL | mod_decl!(foo);
| ^^^
error: aborting due to previous error

View File

@ -26,7 +26,12 @@ error: expected one of `move`, `|`, or `||`, found the end of the macro arm
--> <::edition_kw_macro_2015::passes_ident macros>:1:25
|
LL | ( $ i : ident ) => ( $ i )
| ^
| ^ expected one of `move`, `|`, or `||` here
|
::: $DIR/edition-keywords-2018-2015-parsing.rs:26:8
|
LL | if passes_ident!(async) == 1 {}
| -------------------- in this macro invocation
error: aborting due to 5 previous errors

View File

@ -26,7 +26,12 @@ error: expected one of `move`, `|`, or `||`, found the end of the macro arm
--> <::edition_kw_macro_2018::passes_ident macros>:1:25
|
LL | ( $ i : ident ) => ( $ i )
| ^
| ^ expected one of `move`, `|`, or `||` here
|
::: $DIR/edition-keywords-2018-2018-parsing.rs:26:8
|
LL | if passes_ident!(async) == 1 {}
| -------------------- in this macro invocation
error: aborting due to 5 previous errors

View File

@ -5,7 +5,7 @@ LL | macro_rules! empty { () => () }
| -- in this macro arm
...
LL | _ => { empty!() }
| ^^^^^^^^ in this macro expansion
| ^^^^^^^^ expected expression
error: aborting due to previous error