diff options
| -rw-r--r-- | compiler/rustc_expand/src/mbe/diagnostics.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_resolve/messages.ftl | 3 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/errors.rs | 6 | ||||
| -rw-r--r-- | tests/ui/macros/macro-rules-attr-error.rs | 39 | ||||
| -rw-r--r-- | tests/ui/macros/macro-rules-attr-error.stderr | 55 |
6 files changed, 108 insertions, 29 deletions
diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 5b9d56ee2bc..80433b7be91 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -58,18 +58,6 @@ pub(super) fn failed_to_match_macro( let Some(BestFailure { token, msg: label, remaining_matcher, .. }) = tracker.best_failure else { - // FIXME: we should report this at macro resolution time, as we do for - // `resolve_macro_cannot_use_as_attr`. We can do that once we track multiple macro kinds for a - // Def. - if attr_args.is_none() && !rules.iter().any(|rule| matches!(rule, MacroRule::Func { .. })) { - let msg = format!("macro has no rules for function-like invocation `{name}!`"); - let mut err = psess.dcx().struct_span_err(sp, msg); - if !def_head_span.is_dummy() { - let msg = "this macro has no rules for function-like invocation"; - err.span_label(def_head_span, msg); - } - return (sp, err.emit()); - } return (sp, psess.dcx().span_delayed_bug(sp, "failed to match a macro")); }; diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index ceef558c0cf..d5ff8a4b609 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -242,6 +242,9 @@ resolve_lowercase_self = attempt to use a non-constant value in a constant .suggestion = try using `Self` +resolve_macro_cannot_use_as_fn_like = + `{$ident}` exists, but has no rules for function-like invocation + resolve_macro_cannot_use_as_attr = `{$ident}` exists, but has no `attr` rules diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 217be7be178..a78cf028795 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1555,11 +1555,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let Some((def_id, unused_ident)) = unused_macro { let scope = self.local_macro_def_scopes[&def_id]; let parent_nearest = parent_scope.module.nearest_parent_mod(); - if Some(parent_nearest) == scope.opt_def_id() { + let unused_macro_kinds = self.local_macro_map[def_id].ext.macro_kinds(); + if !unused_macro_kinds.contains(macro_kind.into()) { match macro_kind { MacroKind::Bang => { - err.subdiagnostic(MacroDefinedLater { span: unused_ident.span }); - err.subdiagnostic(MacroSuggMovePosition { span: ident.span, ident }); + err.subdiagnostic(MacroRulesNot::Func { span: unused_ident.span, ident }); } MacroKind::Attr => { err.subdiagnostic(MacroRulesNot::Attr { span: unused_ident.span, ident }); @@ -1568,14 +1568,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { err.subdiagnostic(MacroRulesNot::Derive { span: unused_ident.span, ident }); } } - return; } - } - - if self.macro_names.contains(&ident.normalize_to_macros_2_0()) { - err.subdiagnostic(AddedMacroUse); - return; + if Some(parent_nearest) == scope.opt_def_id() { + err.subdiagnostic(MacroDefinedLater { span: unused_ident.span }); + err.subdiagnostic(MacroSuggMovePosition { span: ident.span, ident }); + return; + } } if ident.name == kw::Default @@ -1651,6 +1650,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { err.subdiagnostic(note); return; } + + if self.macro_names.contains(&ident.normalize_to_macros_2_0()) { + err.subdiagnostic(AddedMacroUse); + return; + } } /// Given an attribute macro that failed to be resolved, look for `derive` macros that could diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 2747ba135ed..a1d62ba7a68 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -672,6 +672,12 @@ pub(crate) struct MacroSuggMovePosition { #[derive(Subdiagnostic)] pub(crate) enum MacroRulesNot { + #[label(resolve_macro_cannot_use_as_fn_like)] + Func { + #[primary_span] + span: Span, + ident: Ident, + }, #[label(resolve_macro_cannot_use_as_attr)] Attr { #[primary_span] diff --git a/tests/ui/macros/macro-rules-attr-error.rs b/tests/ui/macros/macro-rules-attr-error.rs index 1c8bb251e20..81eadb6692f 100644 --- a/tests/ui/macros/macro-rules-attr-error.rs +++ b/tests/ui/macros/macro-rules-attr-error.rs @@ -7,9 +7,46 @@ macro_rules! local_attr { //~^^ ERROR: local_attr } +//~v NOTE: `fn_only` exists, but has no `attr` rules +macro_rules! fn_only { + {} => {} +} + +//~v NOTE: `attr_only` exists, but has no rules for function-like invocation +macro_rules! attr_only { + attr() {} => {} +} + fn main() { + //~v NOTE: in this expansion of #[local_attr] #[local_attr] struct S; - local_attr!(arg); //~ ERROR: macro has no rules for function-like invocation + //~vv ERROR: cannot find macro `local_attr` in this scope + //~| NOTE: `local_attr` is in scope, but it is an attribute + local_attr!(arg); + + //~v ERROR: cannot find attribute `fn_only` in this scope + #[fn_only] + struct S; + + attr_only!(); //~ ERROR: cannot find macro `attr_only` in this scope +} + +//~vv ERROR: cannot find attribute `forward_referenced_attr` in this scope +//~| NOTE: consider moving the definition of `forward_referenced_attr` before this call +#[forward_referenced_attr] +struct S; + +//~v NOTE: a macro with the same name exists, but it appears later +macro_rules! forward_referenced_attr { + attr() {} => {} +} + +//~vv ERROR: cannot find attribute `cyclic_attr` in this scope +//~| NOTE: consider moving the definition of `cyclic_attr` before this call +#[cyclic_attr] +//~v NOTE: a macro with the same name exists, but it appears later +macro_rules! cyclic_attr { + attr() {} => {} } diff --git a/tests/ui/macros/macro-rules-attr-error.stderr b/tests/ui/macros/macro-rules-attr-error.stderr index 177b7009384..674d35091b6 100644 --- a/tests/ui/macros/macro-rules-attr-error.stderr +++ b/tests/ui/macros/macro-rules-attr-error.stderr @@ -9,14 +9,55 @@ LL | #[local_attr] | = note: this error originates in the attribute macro `local_attr` (in Nightly builds, run with -Z macro-backtrace for more info) -error: macro has no rules for function-like invocation `local_attr!` - --> $DIR/macro-rules-attr-error.rs:14:5 +error: cannot find macro `local_attr` in this scope + --> $DIR/macro-rules-attr-error.rs:27:5 | -LL | macro_rules! local_attr { - | ----------------------- this macro has no rules for function-like invocation -... LL | local_attr!(arg); - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ + | + = note: `local_attr` is in scope, but it is an attribute: `#[local_attr]` + +error: cannot find attribute `fn_only` in this scope + --> $DIR/macro-rules-attr-error.rs:30:7 + | +LL | macro_rules! fn_only { + | ------- `fn_only` exists, but has no `attr` rules +... +LL | #[fn_only] + | ^^^^^^^ + +error: cannot find macro `attr_only` in this scope + --> $DIR/macro-rules-attr-error.rs:33:5 + | +LL | macro_rules! attr_only { + | --------- `attr_only` exists, but has no rules for function-like invocation +... +LL | attr_only!(); + | ^^^^^^^^^ + +error: cannot find attribute `forward_referenced_attr` in this scope + --> $DIR/macro-rules-attr-error.rs:38:3 + | +LL | #[forward_referenced_attr] + | ^^^^^^^^^^^^^^^^^^^^^^^ consider moving the definition of `forward_referenced_attr` before this call + | +note: a macro with the same name exists, but it appears later + --> $DIR/macro-rules-attr-error.rs:42:14 + | +LL | macro_rules! forward_referenced_attr { + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot find attribute `cyclic_attr` in this scope + --> $DIR/macro-rules-attr-error.rs:48:3 + | +LL | #[cyclic_attr] + | ^^^^^^^^^^^ consider moving the definition of `cyclic_attr` before this call + | +note: a macro with the same name exists, but it appears later + --> $DIR/macro-rules-attr-error.rs:50:14 + | +LL | macro_rules! cyclic_attr { + | ^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 6 previous errors |
