Skip to content

Commit 953a1ef

Browse files
committed
fix: better error cases with bad/missing identifiers in MBEs
1 parent 503e129 commit 953a1ef

11 files changed

+88
-48
lines changed

compiler/rustc_parse/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,8 @@ parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of
501501
502502
parse_maybe_missing_let = you might have meant to continue the let-chain
503503
504+
parse_maybe_missing_macro_rules_name = maybe you have forgotten to define a name for this `macro_rules!`
505+
504506
parse_maybe_recover_from_bad_qpath_stage_2 =
505507
missing angle brackets in associated item path
506508
.suggestion = types that don't start with an identifier need to be surrounded with angle brackets in qualified paths

compiler/rustc_parse/src/parser/item.rs

+45-14
Original file line numberDiff line numberDiff line change
@@ -2040,23 +2040,26 @@ impl<'a> Parser<'a> {
20402040

20412041
/// Is this a possibly malformed start of a `macro_rules! foo` item definition?
20422042
fn is_macro_rules_item(&mut self) -> IsMacroRulesItem {
2043-
if self.check_keyword(kw::MacroRules) {
2044-
let macro_rules_span = self.token.span;
2045-
2046-
if self.look_ahead(1, |t| *t == token::Not) && self.look_ahead(2, |t| t.is_ident()) {
2047-
return IsMacroRulesItem::Yes { has_bang: true };
2048-
} else if self.look_ahead(1, |t| (t.is_ident())) {
2049-
// macro_rules foo
2050-
self.sess.emit_err(errors::MacroRulesMissingBang {
2051-
span: macro_rules_span,
2052-
hi: macro_rules_span.shrink_to_hi(),
2053-
});
2043+
if !self.check_keyword(kw::MacroRules) {
2044+
return IsMacroRulesItem::No;
2045+
}
2046+
2047+
let macro_rules_span = self.token.span;
2048+
let has_bang = self.look_ahead(1, |t| *t == token::Not);
20542049

2055-
return IsMacroRulesItem::Yes { has_bang: false };
2050+
// macro_rules foo
2051+
if !has_bang {
2052+
if !self.look_ahead(1, |t| (t.is_ident())) {
2053+
return IsMacroRulesItem::No;
20562054
}
2055+
2056+
self.sess.emit_err(errors::MacroRulesMissingBang {
2057+
span: macro_rules_span,
2058+
hi: macro_rules_span.shrink_to_hi(),
2059+
});
20572060
}
20582061

2059-
IsMacroRulesItem::No
2062+
IsMacroRulesItem::Yes { has_bang }
20602063
}
20612064

20622065
/// Parses a `macro_rules! foo { ... }` declarative macro.
@@ -2070,7 +2073,35 @@ impl<'a> Parser<'a> {
20702073
if has_bang {
20712074
self.expect(&token::Not)?; // `!`
20722075
}
2073-
let ident = self.parse_ident()?;
2076+
2077+
let ident = match self.parse_ident() {
2078+
Ok(ident) => ident,
2079+
Err(mut err) => {
2080+
match (
2081+
&self.token.kind,
2082+
self.look_ahead(1, |token| token.ident()),
2083+
self.look_ahead(2, |token| {
2084+
token.kind == TokenKind::CloseDelim(Delimiter::Parenthesis)
2085+
}),
2086+
) {
2087+
(
2088+
TokenKind::OpenDelim(Delimiter::Parenthesis),
2089+
Some((Ident { span, .. }, _)),
2090+
true,
2091+
) => {
2092+
err.span_note(
2093+
span,
2094+
"try removing the parenthesis around the name for this `macro_rules!`",
2095+
);
2096+
}
2097+
_ => {
2098+
err.note(fluent::parse_maybe_missing_macro_rules_name);
2099+
}
2100+
}
2101+
2102+
return Err(err);
2103+
}
2104+
};
20742105

20752106
if self.eat(&token::Not) {
20762107
// Handle macro_rules! foo!

compiler/rustc_resolve/messages.ftl

-2
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,6 @@ resolve_method_not_member_of_trait =
181181
method `{$method}` is not a member of trait `{$trait_}`
182182
.label = not a member of trait `{$trait_}`
183183
184-
resolve_missing_macro_rules_name = maybe you have forgotten to define a name for this `macro_rules!`
185-
186184
resolve_module_only =
187185
visibility must resolve to a module
188186

compiler/rustc_resolve/src/diagnostics.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_span::{BytePos, Span, SyntaxContext};
2828
use thin_vec::{thin_vec, ThinVec};
2929

3030
use crate::errors::{AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion};
31-
use crate::errors::{ConsiderAddingADerive, ExplicitUnsafeTraits, MaybeMissingMacroRulesName};
31+
use crate::errors::{ConsiderAddingADerive, ExplicitUnsafeTraits};
3232
use crate::imports::{Import, ImportKind};
3333
use crate::late::{PatternSource, Rib};
3434
use crate::path_names_to_string;
@@ -1419,11 +1419,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
14191419
"",
14201420
);
14211421

1422-
if macro_kind == MacroKind::Bang && ident.name == sym::macro_rules {
1423-
err.subdiagnostic(MaybeMissingMacroRulesName { span: ident.span });
1424-
return;
1425-
}
1426-
14271422
if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) {
14281423
err.subdiagnostic(ExplicitUnsafeTraits { span: ident.span, ident });
14291424
return;

compiler/rustc_resolve/src/errors.rs

-7
Original file line numberDiff line numberDiff line change
@@ -665,13 +665,6 @@ pub(crate) struct ExplicitUnsafeTraits {
665665
pub(crate) ident: Ident,
666666
}
667667

668-
#[derive(Subdiagnostic)]
669-
#[note(resolve_missing_macro_rules_name)]
670-
pub(crate) struct MaybeMissingMacroRulesName {
671-
#[primary_span]
672-
pub(crate) span: Span,
673-
}
674-
675668
#[derive(Subdiagnostic)]
676669
#[help(resolve_added_macro_use)]
677670
pub(crate) struct AddedMacroUse;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Ensures MBEs with a missing ident produce a readable error
2+
3+
macro_rules! {
4+
//~^ ERROR: expected identifier, found `{`
5+
//~| NOTE: expected identifier
6+
//~| NOTE: maybe you have forgotten to define a name for this `macro_rules!`
7+
() => {}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: expected identifier, found `{`
2+
--> $DIR/mbe-missing-ident-error.rs:3:14
3+
|
4+
LL | macro_rules! {
5+
| ^ expected identifier
6+
|
7+
= note: maybe you have forgotten to define a name for this `macro_rules!`
8+
9+
error: aborting due to 1 previous error
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Ensures MBEs with a invalid ident produce a readable error
2+
3+
macro_rules! (meepmeep) {
4+
//~^ ERROR: expected identifier, found `(`
5+
//~| NOTE: expected identifier
6+
//~| NOTE: try removing the parenthesis around the name for this `macro_rules!`
7+
() => {}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: expected identifier, found `(`
2+
--> $DIR/mbe-parenthesis-ident-error.rs:3:14
3+
|
4+
LL | macro_rules! (meepmeep) {
5+
| ^ expected identifier
6+
|
7+
note: try removing the parenthesis around the name for this `macro_rules!`
8+
--> $DIR/mbe-parenthesis-ident-error.rs:3:15
9+
|
10+
LL | macro_rules! (meepmeep) {
11+
| ^^^^^^^^
12+
13+
error: aborting due to 1 previous error
14+

tests/ui/resolve/issue-118295.rs

-5
This file was deleted.

tests/ui/resolve/issue-118295.stderr

-14
This file was deleted.

0 commit comments

Comments
 (0)