Improve code suggestion for incorrect macro_rules! usage
This commit is contained in:
parent
605f49b274
commit
caf7cdf558
6 changed files with 89 additions and 27 deletions
|
|
@ -534,7 +534,7 @@ impl<'a> Parser<'a> {
|
|||
match self.parse_delim_args() {
|
||||
// `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
|
||||
Ok(args) => {
|
||||
self.eat_semi_for_macro_if_needed(&args);
|
||||
self.eat_semi_for_macro_if_needed(&args, Some(&path));
|
||||
self.complain_if_pub_macro(vis, false);
|
||||
Ok(MacCall { path, args })
|
||||
}
|
||||
|
|
@ -2392,7 +2392,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
let body = self.parse_delim_args()?;
|
||||
self.eat_semi_for_macro_if_needed(&body);
|
||||
self.eat_semi_for_macro_if_needed(&body, None);
|
||||
self.complain_if_pub_macro(vis, true);
|
||||
|
||||
Ok(ItemKind::MacroDef(
|
||||
|
|
@ -2417,13 +2417,13 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs) {
|
||||
fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs, path: Option<&Path>) {
|
||||
if args.need_semicolon() && !self.eat(exp!(Semi)) {
|
||||
self.report_invalid_macro_expansion_item(args);
|
||||
self.report_invalid_macro_expansion_item(args, path);
|
||||
}
|
||||
}
|
||||
|
||||
fn report_invalid_macro_expansion_item(&self, args: &DelimArgs) {
|
||||
fn report_invalid_macro_expansion_item(&self, args: &DelimArgs, path: Option<&Path>) {
|
||||
let span = args.dspan.entire();
|
||||
let mut err = self.dcx().struct_span_err(
|
||||
span,
|
||||
|
|
@ -2433,17 +2433,32 @@ impl<'a> Parser<'a> {
|
|||
// macros within the same crate (that we can fix), which is sad.
|
||||
if !span.from_expansion() {
|
||||
let DelimSpan { open, close } = args.dspan;
|
||||
err.multipart_suggestion(
|
||||
"change the delimiters to curly braces",
|
||||
vec![(open, "{".to_string()), (close, '}'.to_string())],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.span_suggestion(
|
||||
span.with_neighbor(self.token.span).shrink_to_hi(),
|
||||
"add a semicolon",
|
||||
';',
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
// Check if this looks like `macro_rules!(name) { ... }`
|
||||
// a common mistake when trying to define a macro.
|
||||
if let Some(path) = path
|
||||
&& path.segments.first().is_some_and(|seg| seg.ident.name == sym::macro_rules)
|
||||
&& args.delim == Delimiter::Parenthesis
|
||||
{
|
||||
let replace =
|
||||
if path.span.hi() + rustc_span::BytePos(1) < open.lo() { "" } else { " " };
|
||||
err.multipart_suggestion(
|
||||
"to define a macro, remove the parentheses around the macro name",
|
||||
vec![(open, replace.to_string()), (close, String::new())],
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
err.multipart_suggestion(
|
||||
"change the delimiters to curly braces",
|
||||
vec![(open, "{".to_string()), (close, '}'.to_string())],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.span_suggestion(
|
||||
span.with_neighbor(self.token.span).shrink_to_hi(),
|
||||
"add a semicolon",
|
||||
';',
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue