From 885fc781e9c5578fc7a87cafd9f5fcdc8c8d5ab7 Mon Sep 17 00:00:00 2001 From: bohan Date: Sun, 26 Nov 2023 22:05:13 +0800 Subject: [PATCH] tip for define macro name after `macro_rules!` --- compiler/rustc_resolve/messages.ftl | 2 + compiler/rustc_resolve/src/diagnostics.rs | 34 +++++++++++-- compiler/rustc_resolve/src/errors.rs | 7 +++ tests/ui/resolve/issue-118295.rs | 24 +++++++++ tests/ui/resolve/issue-118295.stderr | 62 +++++++++++++++++++++++ 5 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 tests/ui/resolve/issue-118295.rs create mode 100644 tests/ui/resolve/issue-118295.stderr diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index a5faaaab639a3..f7fca5a9d7b24 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -181,6 +181,8 @@ resolve_method_not_member_of_trait = method `{$method}` is not a member of trait `{$trait_}` .label = not a member of trait `{$trait_}` +resolve_missing_macro_rules_name = maybe you have forgotten to define a name for this `macro_rules` + resolve_module_only = visibility must resolve to a module diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 6c387a385e640..077c003eb48ff 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -27,10 +27,8 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Span, SyntaxContext}; use thin_vec::{thin_vec, ThinVec}; -use crate::errors::{ - AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion, ConsiderAddingADerive, - ExplicitUnsafeTraits, -}; +use crate::errors::{AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion}; +use crate::errors::{ConsiderAddingADerive, ExplicitUnsafeTraits, MaybeMissingMacroRulesName}; use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; use crate::path_names_to_string; @@ -1421,14 +1419,42 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { "", ); + if macro_kind == MacroKind::Bang + && ident.name == sym::macro_rules + && let source_map = self.tcx.sess.source_map() + && let Ok(next_source) = source_map.span_to_next_source(ident.span) + && let Some(brace_offset) = { + // find the first `{` + let chars = next_source.chars().collect::>(); + if chars.len() < 2 || chars[0] != '!' { + None + } else { + let mut idx = 1; + while idx < chars.len() && chars[idx].is_ascii_whitespace() { + idx += 1; + } + (idx < chars.len() && chars[idx] == '{').then_some(idx) + } + } + { + let bang_pos = ident.span.hi().0; + let lo = bang_pos + 1; // the pos after `!` + let hi = bang_pos + brace_offset as u32; // the pos of '{' + let span = ident.span.with_hi(BytePos(hi)).with_lo(BytePos(lo)); + err.subdiagnostic(MaybeMissingMacroRulesName { span }); + return; + } + if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) { err.subdiagnostic(ExplicitUnsafeTraits { span: ident.span, ident }); return; } + if self.macro_names.contains(&ident.normalize_to_macros_2_0()) { err.subdiagnostic(AddedMacroUse); return; } + if ident.name == kw::Default && let ModuleKind::Def(DefKind::Enum, def_id, _) = parent_scope.module.kind { diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 72ff959bbd632..1fdb193e571f1 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -665,6 +665,13 @@ pub(crate) struct ExplicitUnsafeTraits { pub(crate) ident: Ident, } +#[derive(Subdiagnostic)] +#[note(resolve_missing_macro_rules_name)] +pub(crate) struct MaybeMissingMacroRulesName { + #[primary_span] + pub(crate) span: Span, +} + #[derive(Subdiagnostic)] #[help(resolve_added_macro_use)] pub(crate) struct AddedMacroUse; diff --git a/tests/ui/resolve/issue-118295.rs b/tests/ui/resolve/issue-118295.rs new file mode 100644 index 0000000000000..becd254fd8e86 --- /dev/null +++ b/tests/ui/resolve/issue-118295.rs @@ -0,0 +1,24 @@ +macro_rules! {} +//~^ ERROR cannot find macro `macro_rules` in this scope +//~| NOTE maybe you have forgotten to define a name for this `macro_rules` + +macro_rules!{} +//~^ ERROR cannot find macro `macro_rules` in this scope +//~| NOTE maybe you have forgotten to define a name for this `macro_rules` + +macro_rules! {} +//~^ ERROR cannot find macro `macro_rules` in this scope +//~| NOTE maybe you have forgotten to define a name for this `macro_rules` + +macro_rules! { + +} +//~^^^ ERROR cannot find macro `macro_rules` in this scope +//~| NOTE maybe you have forgotten to define a name for this `macro_rules` + +macro_rules![]; +//~^ ERROR cannot find macro `macro_rules` in this scope +macro_rules!(); +//~^ ERROR cannot find macro `macro_rules` in this scope + +fn main() {} diff --git a/tests/ui/resolve/issue-118295.stderr b/tests/ui/resolve/issue-118295.stderr new file mode 100644 index 0000000000000..8daf576c20a2d --- /dev/null +++ b/tests/ui/resolve/issue-118295.stderr @@ -0,0 +1,62 @@ +error: cannot find macro `macro_rules` in this scope + --> $DIR/issue-118295.rs:21:1 + | +LL | macro_rules!(); + | ^^^^^^^^^^^ + +error: cannot find macro `macro_rules` in this scope + --> $DIR/issue-118295.rs:19:1 + | +LL | macro_rules![]; + | ^^^^^^^^^^^ + +error: cannot find macro `macro_rules` in this scope + --> $DIR/issue-118295.rs:13:1 + | +LL | macro_rules! { + | ^^^^^^^^^^^ + | +note: maybe you have forgotten to define a name for this `macro_rules` + --> $DIR/issue-118295.rs:13:13 + | +LL | macro_rules! { + | ^ + +error: cannot find macro `macro_rules` in this scope + --> $DIR/issue-118295.rs:9:1 + | +LL | macro_rules! {} + | ^^^^^^^^^^^ + | +note: maybe you have forgotten to define a name for this `macro_rules` + --> $DIR/issue-118295.rs:9:13 + | +LL | macro_rules! {} + | ^^ + +error: cannot find macro `macro_rules` in this scope + --> $DIR/issue-118295.rs:5:1 + | +LL | macro_rules!{} + | ^^^^^^^^^^^ + | +note: maybe you have forgotten to define a name for this `macro_rules` + --> $DIR/issue-118295.rs:5:13 + | +LL | macro_rules!{} + | ^ + +error: cannot find macro `macro_rules` in this scope + --> $DIR/issue-118295.rs:1:1 + | +LL | macro_rules! {} + | ^^^^^^^^^^^ + | +note: maybe you have forgotten to define a name for this `macro_rules` + --> $DIR/issue-118295.rs:1:13 + | +LL | macro_rules! {} + | ^ + +error: aborting due to 6 previous errors +