Rollup merge of #145153 - joshtriplett:macro-kinds-plural, r=petrochenkov

Handle macros with multiple kinds, and improve errors

(I recommend reviewing this commit-by-commit.)

Switch to a bitflags `MacroKinds` to support macros with more than one kind

Review everything that uses `MacroKind`, and switch anything that could refer to more than one kind to use `MacroKinds`.

Add a new `SyntaxExtensionKind::MacroRules` for `macro_rules!` macros, using the concrete `MacroRulesMacroExpander` type, and have it track which kinds it can handle. Eliminate the separate optional `attr_ext`, now that a `SyntaxExtension` can handle multiple macro kinds.

This also avoids the need to downcast when calling methods on `MacroRulesMacroExpander`, such as `get_unused_rule`.

Integrate macro kind checking into name resolution's `sub_namespace_match`, so that we only find a macro if it's the right type, and eliminate the special-case hack for attributes.

This allows detecting and report macro kind mismatches early, and more precisely, improving various error messages. In particular, this eliminates the case in `failed_to_match_macro` to check for a function-like invocation of a macro with no function-like rules.

Instead, macro kind mismatches now result in an unresolved macro, and we detect this case in `unresolved_macro_suggestions`, which now carefully distinguishes between a kind mismatch and other errors.

This also handles cases of forward-referenced attributes and cyclic attributes.

----

In this PR, I've minimally fixed up `rustdoc` so that it compiles and passes tests. This is just the minimal necessary fixes to handle the switch to `MacroKinds`, and it only works for macros that don't actually have multiple kinds. This will panic (with a `todo!`) if it encounters a macro with multiple kinds.

rustdoc needs further fixes to handle macros with multiple kinds, and to handle attributes and derive macros that aren't proc macros. I'd appreciate some help from a rustdoc expert on that.

----

r? ````````@petrochenkov````````
This commit is contained in:
Guillaume Gomez 2025-08-13 18:43:01 +02:00 committed by GitHub
commit cf42ac6bf2
2 changed files with 3 additions and 5 deletions

View file

@ -8,7 +8,6 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, QPath, TyKind, Variant, VariantData};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::impl_lint_pass;
use rustc_span::MacroKind;
use rustc_span::symbol::Symbol;
declare_clippy_lint! {
@ -503,8 +502,8 @@ impl LateLintPass<'_> for ItemNameRepetitions {
);
}
let is_macro_rule = matches!(item.kind, ItemKind::Macro(_, _, MacroKind::Bang));
if both_are_public && item_camel.len() > mod_camel.len() && !is_macro_rule {
let is_macro = matches!(item.kind, ItemKind::Macro(_, _, _));
if both_are_public && item_camel.len() > mod_camel.len() && !is_macro {
let matching = count_match_start(mod_camel, &item_camel);
let rmatching = count_match_end(mod_camel, &item_camel);
let nchars = mod_camel.chars().count();

View file

@ -7,7 +7,6 @@ use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::impl_lint_pass;
use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::hygiene::MacroKind;
declare_clippy_lint! {
/// ### What it does
@ -89,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
// We ignore macro exports. And `ListStem` uses, which aren't interesting.
fn is_ignorable_export<'tcx>(item: &'tcx Item<'tcx>) -> bool {
if let ItemKind::Use(path, kind) = item.kind {
let ignore = matches!(path.res.macro_ns, Some(Res::Def(DefKind::Macro(MacroKind::Bang), _)))
let ignore = matches!(path.res.macro_ns, Some(Res::Def(DefKind::Macro(_), _)))
|| kind == UseKind::ListStem;
if ignore {
return true;