about summary refs log tree commit diff
path: root/compiler/rustc_expand/src/base.rs
AgeCommit message (Collapse)AuthorLines
2025-10-01mbe: Support `unsafe` attribute rulesJosh Triplett-1/+16
2025-09-26Rollup merge of #146849 - joshtriplett:macro-reduce-legacy-bang, r=petrochenkovMatthias Krüger-13/+10
Reduce some uses of `LegacyBang` - **Switch `dummy_bang` from `LegacyBang` to `Bang`** - **mbe: Switch dummy extension used for errors from `LegacyBang` to `Bang`**
2025-09-22Switch `dummy_bang` from `LegacyBang` to `Bang`Josh Triplett-13/+10
2025-09-21Port #[macro_export] to the new attribute parsing infrastructureJonathan Brouwer-3/+3
Co-authored-by: Anne Stijns <anstijns@gmail.com>
2025-09-08fixup limit handling codeJana Dönszelmann-1/+2
2025-08-22Refactor lint buffering to avoid requiring a giant enumJosh Triplett-2/+2
Lint buffering currently relies on a giant enum `BuiltinLintDiag` containing all the lints that might potentially get buffered. In addition to being an unwieldy enum in a central crate, this also makes `rustc_lint_defs` a build bottleneck: it depends on various types from various crates (with a steady pressure to add more), and many crates depend on it. Having all of these variants in a separate crate also prevents detecting when a variant becomes unused, which we can do with a dedicated type defined and used in the same crate. Refactor this to use a dyn trait, to allow using `LintDiagnostic` types directly. This requires boxing, but all of this is already on the slow path (emitting an error). Because the existing `BuiltinLintDiag` requires some additional types in order to decorate some variants, which are only available later in `rustc_lint`, use an enum `DecorateDiagCompat` to handle both the `dyn LintDiagnostic` case and the `BuiltinLintDiag` case.
2025-08-13Rollup merge of #145153 - joshtriplett:macro-kinds-plural, r=petrochenkovGuillaume Gomez-6/+42
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````````
2025-08-12Expand documentation of `GlobDelegation`Josh Triplett-0/+2
I discovered this via research through the git log, and I want to leave additional guidance for future macro spelunkers.
2025-08-12Switch to a bitflags `MacroKinds` to support macros with more than one kindJosh Triplett-6/+40
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.
2025-08-11Port `#[allow_internal_unsafe]` to the new attribute system (attempt 2)Sasha Pourcelot-4/+1
2025-08-09remove `P`Deadbeef-48/+47
2025-08-08Revert "Port `#[allow_internal_unsafe]` to the new attribute system"Jana Dönszelmann-1/+4
This reverts commit 4f7a6ace9e2f2192af7b5d32f4b1664189e0e143.
2025-08-07Port `#[allow_internal_unsafe]` to the new attribute systemSasha Pourcelot-4/+1
2025-07-31remove rustc_attr_data_structuresJana Dönszelmann-1/+2
2025-07-28Rollup merge of #143607 - JonathanBrouwer:proc_macro_attrs, ↵Matthias Krüger-86/+14
r=jdonszelmann,traviscross Port the proc macro attributes to the new attribute parsing infrastructure Ports `#[proc_macro]`, `#[proc_macro_attribute]`, `#[proc_macro_derive]` and `#[rustc_builtin_macro]` to the new attribute parsing infrastructure for https://github.com/rust-lang/rust/issues/131229#issuecomment-2971351163 I've split this PR into commits for reviewability, and left some comments to clarify things I did 4 related attributes in one PR because they share a lot of their code and logic, and doing them separately is kind of annoying as I need to leave both the old and new parsing in place then. r? ``@oli-obk`` cc ``@jdonszelmann``
2025-07-27split up define into define_extern and define_localLorrensP-2158466-1/+1
2025-07-26Remove now un-used codeJonathan Brouwer-74/+0
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
2025-07-26Use the new attributes throughout the codebaseJonathan Brouwer-12/+14
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
2025-07-25Stop compilation if macro expansion failedGuillaume Gomez-0/+8
2025-07-22mbe: Use concrete type for `get_unused_rule`Josh Triplett-6/+3
Rather than adding `get_unused_rule` to the `TTMacroExpander` trait, put it on the concrete `MacroRulesMacroExpander`, and downcast to that type via `Any` in order to call it. Suggested-by: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
2025-07-17resolve: Change `&mut Resolver` to `&Resolver` when possibleVadim Petrochenkov-1/+1
2025-07-15Define datastructures for `#[cfg]` attribute, move StrippedCfgItemJonathan Brouwer-2/+8
2025-07-13make `cfg_select` a builtin macroFolkert de Vries-0/+20
2025-07-05mbe: Defer checks for `compile_error!` until reporting an unused macro ruleJosh Triplett-0/+4
The MBE parser checks rules at initial parse time to see if their RHS has `compile_error!` in it, and returns a list of rule indexes and LHS spans that don't map to `compile_error!`, for use in unused macro rule checking. Instead, have the unused macro rule reporting ask the macro for the rule to report, and let the macro check at that time. That avoids checking rules unless they're unused. In the process, refactor the data structure used to store macro rules, to group the LHS and RHS (and LHS span) of each rule together, and refactor the unused rule tracking to only track rule indexes. This ends up being a net simplification, and reduction in code size.
2025-07-03Port `#[target_feature]` to the new attribute parsing infrastructureJonathan Brouwer-1/+1
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
2025-06-25Don't give APITs names with macro expansion placeholder fragments in itMichael Goulet-0/+4
2025-06-16Remove an `njn:` comment accidentaly left behind.Nicholas Nethercote-1/+2
2025-06-12Introduce `-Zmacro-stats`.Nicholas Nethercote-1/+5
It collects data about macro expansions and prints them in a table after expansion finishes. It's very useful for detecting macro bloat, especially for proc macros. Details: - It measures code snippets by pretty-printing them and then measuring lines and bytes. This required a bunch of additional pretty-printing plumbing, in `rustc_ast_pretty` and `rustc_expand`. - The measurement is done in `MacroExpander::expand_invoc`. - The measurements are stored in `ExtCtxt::macro_stats`.
2025-06-06Rollup merge of #141603 - nnethercote:reduce-P, r=fee1-deadGuillaume Gomez-1/+1
Reduce `ast::ptr::P` to a typedef of `Box` As per the MCP at https://github.com/rust-lang/compiler-team/issues/878. r? `@fee1-dead`
2025-05-28Reorder `ast::ItemKind::{Struct,Enum,Union}` fields.Nicholas Nethercote-1/+1
So they match the order of the parts in the source code, e.g.: ``` struct Foo<T, U> { t: T, u: U } <-><----> <------------> / | \ ident generics variant_data ```
2025-05-27Reduce `P<T>` to a typedef of `Box<T>`.Nicholas Nethercote-1/+1
Keep the `P` constructor function for now, to minimize immediate churn. All the `into_inner` calls are removed, which is nice.
2025-05-18Remove rustc_attr_data_structures re-export from rustc_attr_parsingmejrs-1/+1
2025-04-17Replace infallible `name_or_empty` methods with fallible `name` methods.Nicholas Nethercote-4/+4
I'm removing empty identifiers everywhere, because in practice they always mean "no identifier" rather than "empty identifier". (An empty identifier is impossible.) It's better to use `Option` to mean "no identifier" because you then can't forget about the "no identifier" possibility. Some specifics: - When testing an attribute for a single name, the commit uses the `has_name` method. - When testing an attribute for multiple names, the commit uses the new `has_any_name` method. - When using `match` on an attribute, the match arms now have `Some` on them. In the tests, we now avoid printing empty identifiers by not printing the identifier in the `error:` line at all, instead letting the carets point out the problem.
2025-04-10Rename some `name` variables as `ident`.Nicholas Nethercote-1/+1
It bugs me when variables of type `Ident` are called `name`. It leads to silly things like `name.name`. `Ident` variables should be called `ident`, and `name` should be used for variables of type `Symbol`. This commit improves things by by doing `s/name/ident/` on a bunch of `Ident` variables. Not all of them, but a decent chunk.
2025-04-01Move `ast::Item::ident` into `ast::ItemKind`.Nicholas Nethercote-4/+3
`ast::Item` has an `ident` field. - It's always non-empty for these item kinds: `ExternCrate`, `Static`, `Const`, `Fn`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`, `Trait`, `TraitAlias`, `MacroDef`, `Delegation`. - It's always empty for these item kinds: `Use`, `ForeignMod`, `GlobalAsm`, `Impl`, `MacCall`, `DelegationMac`. There is a similar story for `AssocItemKind` and `ForeignItemKind`. Some sites that handle items check for an empty ident, some don't. This is a very C-like way of doing things, but this is Rust, we have sum types, we can do this properly and never forget to check for the exceptional case and never YOLO possibly empty identifiers (or possibly dummy spans) around and hope that things will work out. The commit is large but it's mostly obvious plumbing work. Some notable things. - `ast::Item` got 8 bytes bigger. This could be avoided by boxing the fields within some of the `ast::ItemKind` variants (specifically: `Struct`, `Union`, `Enum`). I might do that in a follow-up; this commit is big enough already. - For the visitors: `FnKind` no longer needs an `ident` field because the `Fn` within how has one. - In the parser, the `ItemInfo` typedef is no longer needed. It was used in various places to return an `Ident` alongside an `ItemKind`, but now the `Ident` (if present) is within the `ItemKind`. - In a few places I renamed identifier variables called `name` (or `foo_name`) as `ident` (or `foo_ident`), to better match the type, and because `name` is normally used for `Symbol`s. It's confusing to see something like `foo_name.name`.
2025-03-25Track whether an assoc item is in a trait impl or an inherent implOli Scherer-1/+14
2025-03-19Allow builtin macros to be used more than once.Mara Bos-10/+11
This removes E0773 "A builtin-macro was defined more than once."
2025-03-14Do not suggest using `-Zmacro-backtrace` for builtin macrosEsteban Küber-4/+8
For macros that are implemented on the compiler, we do *not* mention the `-Zmacro-backtrace` flag. This includes `derive`s and standard macros.
2025-03-07Remove `NtItem` and `NtStmt`.Nicholas Nethercote-15/+34
This involves replacing `nt_pretty_printing_compatibility_hack` with `stream_pretty_printing_compatibility_hack`. The handling of statements in `transcribe` is slightly different to other nonterminal kinds, due to the lack of `from_ast` implementation for empty statements. Notable test changes: - `tests/ui/proc-macro/expand-to-derive.rs`: the diff looks large but the only difference is the insertion of a single invisible-delimited group around a metavar.
2025-03-01Implment `#[cfg]` and `#[cfg_attr]` in `where` clausesFrank King-0/+16
2025-02-24Introduce new-style attribute parsers for several attributesJana Dönszelmann-13/+20
note: compiler compiles but librustdoc and clippy don't
2025-02-03tree-wide: parallel: Fully removed all `Lrc`, replaced with `Arc`Askar Safin-4/+5
2025-01-08Rename PatKind::Lit to ExprOli Scherer-1/+1
2024-12-18Re-export more `rustc_span::symbol` things from `rustc_span`.Nicholas Nethercote-2/+1
`rustc_span::symbol` defines some things that are re-exported from `rustc_span`, such as `Symbol` and `sym`. But it doesn't re-export some closely related things such as `Ident` and `kw`. So you can do `use rustc_span::{Symbol, sym}` but you have to do `use rustc_span::symbol::{Ident, kw}`, which is inconsistent for no good reason. This commit re-exports `Ident`, `kw`, and `MacroRulesNormalizedIdent`, and changes many `rustc_span::symbol::` qualifiers in `compiler/` to `rustc_span::`. This is a 200+ net line of code reduction, mostly because many files with two `use rustc_span` items can be reduced to one.
2024-12-16rename rustc_attr to rustc_attr_parsing and create rustc_attr_data_structuresJonathan Dönszelmann-2/+2
2024-12-16split attributesJonathan Dönszelmann-6/+6
2024-12-15Add hir::AttributeJonathan Dönszelmann-8/+10
2024-11-10ensure that all publicly reachable const fn have const stability infoRalf Jung-3/+1
2024-10-25Re-do recursive const stability checksRalf Jung-1/+3
Fundamentally, we have *three* disjoint categories of functions: 1. const-stable functions 2. private/unstable functions that are meant to be callable from const-stable functions 3. functions that can make use of unstable const features This PR implements the following system: - `#[rustc_const_stable]` puts functions in the first category. It may only be applied to `#[stable]` functions. - `#[rustc_const_unstable]` by default puts functions in the third category. The new attribute `#[rustc_const_stable_indirect]` can be added to such a function to move it into the second category. - `const fn` without a const stability marker are in the second category if they are still unstable. They automatically inherit the feature gate for regular calls, it can now also be used for const-calls. Also, several holes in recursive const stability checking are being closed. There's still one potential hole that is hard to avoid, which is when MIR building automatically inserts calls to a particular function in stable functions -- which happens in the panic machinery. Those need to *not* be `rustc_const_unstable` (or manually get a `rustc_const_stable_indirect`) to be sure they follow recursive const stability. But that's a fairly rare and special case so IMO it's fine. The net effect of this is that a `#[unstable]` or unmarked function can be constified simply by marking it as `const fn`, and it will then be const-callable from stable `const fn` and subject to recursive const stability requirements. If it is publicly reachable (which implies it cannot be unmarked), it will be const-unstable under the same feature gate. Only if the function ever becomes `#[stable]` does it need a `#[rustc_const_unstable]` or `#[rustc_const_stable]` marker to decide if this should also imply const-stability. Adding `#[rustc_const_unstable]` is only needed for (a) functions that need to use unstable const lang features (including intrinsics), or (b) `#[stable]` functions that are not yet intended to be const-stable. Adding `#[rustc_const_stable]` is only needed for functions that are actually meant to be directly callable from stable const code. `#[rustc_const_stable_indirect]` is used to mark intrinsics as const-callable and for `#[rustc_const_unstable]` functions that are actually called from other, exposed-on-stable `const fn`. No other attributes are required.
2024-10-22Rollup merge of #125205 - ChrisDenton:verbatim-include, r=jieyouxuMatthias Krüger-1/+7
Fixup Windows verbatim paths when used with the `include!` macro On Windows, the following code can fail if the `OUT_DIR` environment variable is a [verbatim path](https://doc.rust-lang.org/std/path/enum.Prefix.html) (i.e. begins with `\\?\`): ```rust include!(concat!(env!("OUT_DIR"), "/src/repro.rs")); ``` This is because verbatim paths treat `/` literally, as if it were just another character in the file name. The good news is that the standard library already has code to fix this. We can simply use `components` to normalize the path so it works as intended.