add suggestions to invalid macro item error

This commit is contained in:
Andy Russell 2019-03-10 21:01:53 -04:00
parent cf6d881ac1
commit 5abd6d9492
No known key found for this signature in database
GPG key ID: BE2221033EDBC374
5 changed files with 85 additions and 24 deletions

View file

@ -5116,12 +5116,8 @@ impl<'a> Parser<'a> {
let ident = self.parse_ident()?; let ident = self.parse_ident()?;
let (delim, tokens) = self.expect_delimited_token_tree()?; let (delim, tokens) = self.expect_delimited_token_tree()?;
if delim != MacDelimiter::Brace { if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
if !self.eat(&token::Semi) { self.report_invalid_macro_expansion_item();
let msg = "macros that expand to items must either \
be surrounded with braces or followed by a semicolon";
self.span_err(self.prev_span, msg);
}
} }
(ident, ast::MacroDef { tokens: tokens, legacy: true }) (ident, ast::MacroDef { tokens: tokens, legacy: true })
@ -5264,13 +5260,8 @@ impl<'a> Parser<'a> {
// if it has a special ident, it's definitely an item // if it has a special ident, it's definitely an item
// //
// Require a semicolon or braces. // Require a semicolon or braces.
if style != MacStmtStyle::Braces { if style != MacStmtStyle::Braces && !self.eat(&token::Semi) {
if !self.eat(&token::Semi) { self.report_invalid_macro_expansion_item();
self.span_err(self.prev_span,
"macros that expand to items must \
either be surrounded with braces or \
followed by a semicolon");
}
} }
let span = lo.to(hi); let span = lo.to(hi);
Stmt { Stmt {
@ -8360,13 +8351,8 @@ impl<'a> Parser<'a> {
}; };
// eat a matched-delimiter token tree: // eat a matched-delimiter token tree:
let (delim, tts) = self.expect_delimited_token_tree()?; let (delim, tts) = self.expect_delimited_token_tree()?;
if delim != MacDelimiter::Brace { if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
if !self.eat(&token::Semi) { self.report_invalid_macro_expansion_item();
self.span_err(self.prev_span,
"macros that expand to items must either \
be surrounded with braces or followed by \
a semicolon");
}
} }
let hi = self.prev_span; let hi = self.prev_span;
@ -8597,6 +8583,25 @@ impl<'a> Parser<'a> {
} }
} }
} }
fn report_invalid_macro_expansion_item(&self) {
self.struct_span_err(
self.prev_span,
"macros that expand to items must be delimited with braces or followed by a semicolon",
).multipart_suggestion(
"change the delimiters to curly braces",
vec![
(self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), String::from(" {")),
(self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)), '}'.to_string()),
],
Applicability::MaybeIncorrect,
).span_suggestion(
self.sess.source_map.next_point(self.prev_span),
"add a semicolon",
';'.to_string(),
Applicability::MaybeIncorrect,
).emit();
}
} }
pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) { pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {

View file

@ -12,7 +12,7 @@ pub fn main() {
foo!(); foo!();
assert!({one! two()}); assert!({one! two()});
//~^ ERROR macros that expand to items must either be surrounded with braces or followed by a //~^ ERROR macros that expand to items
//~| ERROR cannot find macro `one!` in this scope //~| ERROR cannot find macro `one!` in this scope
//~| ERROR mismatched types //~| ERROR mismatched types

View file

@ -1,8 +1,16 @@
error: macros that expand to items must either be surrounded with braces or followed by a semicolon error: macros that expand to items must be delimited with braces or followed by a semicolon
--> $DIR/issue-10536.rs:14:22 --> $DIR/issue-10536.rs:14:22
| |
LL | assert!({one! two()}); LL | assert!({one! two()});
| ^^ | ^^
help: change the delimiters to curly braces
|
LL | assert!({one! two {}});
| ^^
help: add a semicolon
|
LL | assert!({one! two();});
| ^
error: expected `(` or `{`, found `}` error: expected `(` or `{`, found `}`
--> $DIR/issue-10536.rs:21:22 --> $DIR/issue-10536.rs:21:22

View file

@ -1,4 +1,15 @@
macro_rules! foo() //~ ERROR semicolon macro_rules! foo() //~ ERROR semicolon
//~| ERROR unexpected end of macro
macro_rules! bar {
($($tokens:tt)*) => {}
}
bar!( //~ ERROR semicolon
blah
blah
blah
)
fn main() { fn main() {
} }

View file

@ -1,8 +1,45 @@
error: macros that expand to items must either be surrounded with braces or followed by a semicolon error: macros that expand to items must be delimited with braces or followed by a semicolon
--> $DIR/macros-no-semicolon-items.rs:1:17 --> $DIR/macros-no-semicolon-items.rs:1:17
| |
LL | macro_rules! foo() LL | macro_rules! foo()
| ^^ | ^^
help: change the delimiters to curly braces
|
LL | macro_rules! foo {}
| ^^
help: add a semicolon
|
LL | macro_rules! foo();
| ^
error: aborting due to previous error error: macros that expand to items must be delimited with braces or followed by a semicolon
--> $DIR/macros-no-semicolon-items.rs:8:5
|
LL | bar!(
| _____^
LL | | blah
LL | | blah
LL | | blah
LL | | )
| |_^
help: change the delimiters to curly braces
|
LL | bar! {
LL | blah
LL | blah
LL | blah
LL | }
|
help: add a semicolon
|
LL | );
| ^
error: unexpected end of macro invocation
--> $DIR/macros-no-semicolon-items.rs:1:1
|
LL | macro_rules! foo()
| ^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments
error: aborting due to 3 previous errors