about summary refs log tree commit diff
path: root/compiler/rustc_expand/src/mbe
AgeCommit message (Collapse)AuthorLines
2025-08-19Rollup merge of #139345 - smoelius:into-iter-stability, r=lcnr许杰友 Jieyou Xu (Joe)-0/+1
Extend `QueryStability` to handle `IntoIterator` implementations This PR extends the `rustc::potential_query_instability` lint to check values passed as `IntoIterator` implementations. Full disclosure: I want the lint to warn about this line (please see #138871 for why): https://github.com/rust-lang/rust/blob/aa8f0fd7163a2f23aa958faed30c9c2b77b934a5/src/librustdoc/json/mod.rs#L261 However, the lint warns about several other lines as well. Final note: the functions `get_callee_generic_args_and_args` and `get_input_traits_and_projections` were copied directly from [Clippy's source code](https://github.com/rust-lang/rust/blob/4fd8c04da0674af2c51310c9982370bfadfa1b98/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs#L445-L496).
2025-08-15Extend `QueryStability` to handle `IntoIterator` implementationsSamuel Moelius-0/+1
Fix adjacent code Fix duplicate warning; merge test into `tests/ui-fulldeps/internal-lints` Use `rustc_middle::ty::FnSig::inputs` Address two review comments - https://github.com/rust-lang/rust/pull/139345#discussion_r2109006991 - https://github.com/rust-lang/rust/pull/139345#discussion_r2109058588 Use `Instance::try_resolve` Import `rustc_middle::ty::Ty` as `Ty` rather than `MiddleTy` Simplify predicate handling Add more `#[allow(rustc::potential_query_instability)]` following rebase Remove two `#[allow(rustc::potential_query_instability)]` following rebase Address review comment Update compiler/rustc_lint/src/internal.rs Co-authored-by: lcnr <rust@lcnr.de>
2025-08-14mbe: Handle applying `macro_rules` derivesJosh Triplett-13/+131
Add infrastructure to apply a derive macro to arguments, consuming and returning a `TokenTree` only. Handle `SyntaxExtensionKind::MacroRules` when expanding a derive, if the macro's kinds support derive. Add tests covering various cases of `macro_rules` derives. Note that due to a pre-existing FIXME in `expand.rs`, derives are re-queued and some errors get emitted twice. Duplicate diagnostic suppression makes them not visible, but the FIXME should still get fixed.
2025-08-14mbe: Parse macro `derive` rulesJosh Triplett-6/+53
This handles various kinds of errors, but does not allow applying the derive yet. This adds the feature gate `macro_derive`.
2025-08-12mbe: Rename macro parsing state names to use `Bang` instead of `Not`Josh Triplett-9/+9
The use of `Not` to describe the `!` in `macro_rules!` reads confusingly, and also results in search collisions with the diagnostic structure `MacroRulesNot` elsewhere in the compiler. Rename it to use the more conventional `Bang` for `!`.
2025-08-12Detect and report macro kind mismatches early, and more preciselyJosh Triplett-12/+0
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. Expand test coverage to include all of these cases.
2025-08-12Switch to a bitflags `MacroKinds` to support macros with more than one kindJosh Triplett-11/+15
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-09mbe: Fix typo in attribute tracingJosh Triplett-1/+1
2025-08-08mbe: Handle applying attribute rules with pathsJosh Triplett-24/+176
Add infrastructure to apply an attribute macro given argument tokens and body tokens. Teach the resolver to consider `macro_rules` macros when looking for an attribute via a path. This does not yet handle local `macro_rules` attributes.
2025-08-08mbe: Emit an error if a macro call has no function-like rulesJosh Triplett-3/+21
Add a FIXME for moving this error earlier.
2025-08-08mbe: Parse macro attribute rulesJosh Triplett-20/+85
This handles various kinds of errors, but does not allow applying the attributes yet. This adds the feature gate `macro_attr`.
2025-07-31remove rustc_attr_data_structuresJana Dönszelmann-1/+2
2025-07-25Stop compilation if macro expansion failedGuillaume Gomez-1/+2
2025-07-22mbe: Use concrete type for `get_unused_rule`Josh Triplett-7/+9
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-13Auto merge of #143461 - folkertdev:cfg-select-builtin-macro, r=petrochenkovbors-27/+38
make `cfg_select` a builtin macro tracking issue: https://github.com/rust-lang/rust/issues/115585 This parses mostly the same as the `macro cfg_select` version, except: 1. wrapping in double brackets is no longer supported (or needed): `cfg_select {{ /* ... */ }}` is now rejected. 2. in an expression context, the rhs is no longer wrapped in a block, so that this now works: ```rust fn main() { println!(cfg_select! { unix => { "foo" } _ => { "bar" } }); } ``` 3. a single wildcard rule is now supported: `cfg_select { _ => 1 }` now works I've also added an error if none of the rules evaluate to true, and warnings for any arms that follow the `_` wildcard rule. cc `@traviscross` if I'm missing any feature that should/should not be included r? `@petrochenkov` for the macro logic details
2025-07-13make `cfg_select` a builtin macroFolkert de Vries-27/+38
2025-07-09mbe: Refactor the diagnostic for unrecognized metavariable expressionsTrevor Gross-9/+5
Change to a structural diagnostic, update the valid list, and move the valid list to a note.
2025-07-09mbe: Refactor diagnostics for invalid metavar expression syntaxTrevor Gross-15/+69
Give a more user-friendly diagnostic about the following: * Trailing tokens within braces, e.g. `${foo() extra}` * Missing parentheses, e.g. `${foo}` * Incorrect number of arguments, with a hint about correct usage.
2025-07-06mbe: Clarify comments about error handling in `compile_declarative_macro`Josh Triplett-3/+2
2025-07-06mbe: Factor out a helper to check for unexpected EOF in definitionJosh Triplett-7/+14
Will get called additional times when expanding parsing to cover attributes
2025-07-06mbe: Factor out a helper to check an LHSJosh Triplett-2/+7
This currently gets called only once, but will get called multiple times when handling attributes.
2025-07-06mbe: Simplify compile_declarative_macro by factoring out some variablesJosh Triplett-11/+4
2025-07-05mbe: Defer checks for `compile_error!` until reporting an unused macro ruleJosh Triplett-73/+51
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-05mbe: Simplify a match to a let-elseJosh Triplett-3/+2
2025-07-05mbe: Add a helper to parse a single `TokenTree`Josh Triplett-22/+20
The parser repeatedly invokes the `parse` function, constructing a one-entry vector, and assuming that the return value will be a one-entry vector. Add a helper for that case. This will simplify adding additional callers, and put all the logic in one place to allow potential future simplification of the one-TT case.
2025-07-05mbe: Introduce an enum for which part of a rule we're parsingJosh Triplett-17/+36
Rather than a `bool` that's `true` for the LHS and `false` for the RHS, use a self-documenting enum.
2025-07-03mbe: Gracefully handle macro rules that end after `=>`Josh Triplett-0/+9
Add a test for various cases of invalid macro definitions. Closes: https://github.com/rust-lang/rust/issues/143351
2025-07-02Rollup merge of #143070 - joshtriplett:macro-rules-parse, r=petrochenkovMatthias Krüger-206/+61
Rewrite `macro_rules!` parser to not use the MBE engine itself The `macro_rules!` parser was written to match the series of rules using the macros-by-example (MBE) engine and a hand-written equivalent of the left-hand side of a MBE macro. This was complex to read, difficult to extend, and produced confusing error messages. Because it was using the MBE engine, any parse failure would be reported as if some macro was being applied to the `macro_rules!` invocation itself; for instance, errors would talk about "macro invocation", "macro arguments", and "macro call", when they were actually about the macro *definition*. And in practice, the `macro_rules!` parser only used the MBE engine to extract the left-hand side and right-hand side of each rule as a token tree, and then parsed the rest using a separate parser. Rewrite it to parse the series of rules using a simple loop, instead. This makes it more extensible in the future, and improves error messages. For instance, omitting a semicolon between rules will result in "expected `;`" and "unexpected token", rather than the confusing "no rules expected this token in macro call". This work was greatly aided by pair programming with Vincenzo Palazzo (`@vincenzopalazzo)` and Eric Holk (`@eholk).` For review, I recommend reading the two commits separately.
2025-07-01Rollup merge of #143245 - tgross35:metavariable-expr-organization, ↵Matthias Krüger-52/+57
r=petrochenkov mbe: Add tests and restructure metavariable expressions Add tests that show better diagnostics, and factor `concat` handling to a separate function. Each commit message has further details. This performs the nonfunctional perparation for further changes such as https://github.com/rust-lang/rust/pull/142950 and https://github.com/rust-lang/rust/pull/142975 .
2025-06-30mbe: Move `MetaVarExprConcatElem` closer to where it is usedTrevor Gross-14/+14
Move this structure directly above the `parse_<expr>` functions that return it to keep top-down flow. This is a non-functional change.
2025-06-30mbe: Factor `concat` metavariable handling outTrevor Gross-40/+45
Move the `concat` implementation to a separate function so it is easier to work on. Other metavariable expressions are already split this way. This is a non-functional change.
2025-06-30mbe: Shorten `MetaVarExpr` -> `Mve` in structural diagnosticsTrevor Gross-2/+2
More diagnostic structs related to metavariable expressions will be introduced. Introduce the abbreviation "mve" which is reasonably unambiguous (`rg Mve` and `rg '(\b|_|-)mve(\b|_|-)'` return no results outside of a Thumb target feature) and use it for these diagnostic types. A new module is also created.
2025-06-26mbe: Fold calls to `check_meta_variables` into the parser loopJosh Triplett-18/+8
2025-06-26Rewrite `macro_rules!` parser to not use the MBE engine itselfJosh Triplett-188/+53
The `macro_rules!` parser was written to match the series of rules using the macros-by-example (MBE) engine and a hand-written equivalent of the left-hand side of a MBE macro. This was complex to read, difficult to extend, and produced confusing error messages. Because it was using the MBE engine, any parse failure would be reported as if some macro was being applied to the `macro_rules!` invocation itself; for instance, errors would talk about "macro invocation", "macro arguments", and "macro call", when they were actually about the macro *definition*. And in practice, the `macro_rules!` parser only used the MBE engine to extract the left-hand side and right-hand side of each rule as a token tree, and then parsed the rest using a separate parser. Rewrite it to parse the series of rules using a simple loop, instead. This makes it more extensible in the future, and improves error messages. For instance, omitting a semicolon between rules will result in "expected `;`" and "unexpected token", rather than the confusing "no rules expected this token in macro call". This work was greatly aided by pair programming with Vincenzo Palazzo and Eric Holk.
2025-06-24Rollup merge of #142657 - tgross35:nonoptional-fragment-specifiers-cleanup, ↵Matthias Krüger-132/+115
r=petrochenkov mbe: Clean up code with non-optional `NonterminalKind` Since [rust-lang/rust#128425], the fragment specifier is unconditionally required in all editions. This means `NonTerminalKind` no longer needs to be optional, as we can reject this code during the expansion of `macro_rules!` rather than handling it throughout the code. Do this cleanup here. [rust-lang/rust#128425]: https://github.com/rust-lang/rust/pull/128425
2025-06-24mbe: Use `TokenTree` as the fallback for invalid fragment specifiersTrevor Gross-2/+2
`tt` should match more, so use this for both missing and invalid fragment specifiers. Also remove one unneeded instance of `String`.
2025-06-24mbe: Clean up code with non-optional `NonterminalKind`Trevor Gross-80/+58
Since [1], the fragment specifier is unconditionally required in all editions. This means `NonTerminalKind` no longer needs to be optional, as we can reject this code during the expansion of `macro_rules!` rather than handling it throughout the code. Do this cleanup here. [1]: https://github.com/rust-lang/rust/pull/128425
2025-06-24mbe: Unnest nested matches with let-else and let chainsTrevor Gross-58/+63
Non-functional change to simplify control flow.
2025-06-19mbe: Refactor transcriptionTrevor Gross-348/+389
Introduce `MacroTcbCtx` that holds everything relevant to transcription. This allows for the following changes: * Split `transcribe_sequence` and `transcribe_metavar` out of the heavily nested `transcribe` * Split `metavar_expr_concat` out of `transcribe_metavar_expr` This is a nonfunctional change.
2025-06-19mbe: Move `transcribe_metavar_expr` directly after `transcribe`Trevor Gross-96/+96
Be more consistent with the otherwise top-down organization of this file.
2025-06-12Make `missing_fragment_specifier` an unconditional errorTrevor Gross-19/+6
This was attempted in [1] then reverted in [2] because of fallout. Recently, this was made an edition-dependent error in [3]. Make missing fragment specifiers an unconditional error again. [1]: https://github.com/rust-lang/rust/pull/75516 [2]: https://github.com/rust-lang/rust/pull/80210 [3]: https://github.com/rust-lang/rust/pull/128006
2025-05-18Remove rustc_attr_data_structures re-export from rustc_attr_parsingmejrs-1/+1
2025-04-30ast: Remove token visiting from AST visitorVadim Petrochenkov-16/+16
It's no longer necessary after the removal of nonterminal tokens in #124141.
2025-04-21Remove `token::{Open,Close}Delim`.Nicholas Nethercote-22/+20
By replacing them with `{Open,Close}{Param,Brace,Bracket,Invisible}`. PR #137902 made `ast::TokenKind` more like `lexer::TokenKind` by replacing the compound `BinOp{,Eq}(BinOpToken)` variants with fieldless variants `Plus`, `Minus`, `Star`, etc. This commit does a similar thing with delimiters. It also makes `ast::TokenKind` more similar to `parser::TokenType`. This requires a few new methods: - `TokenKind::is_{,open_,close_}delim()` replace various kinds of pattern matches. - `Delimiter::as_{open,close}_token_kind` are used to convert `Delimiter` values to `TokenKind`. Despite these additions, it's a net reduction in lines of code. This is because e.g. `token::OpenParen` is so much shorter than `token::OpenDelim(Delimiter::Parenthesis)` that many multi-line forms reduce to single line forms. And many places where the number of lines doesn't change are still easier to read, just because the names are shorter, e.g.: ``` - } else if self.token != token::CloseDelim(Delimiter::Brace) { + } else if self.token != token::CloseBrace { ```
2025-04-14Auto merge of #124141 - ↵bors-25/+20
nnethercote:rm-Nonterminal-and-TokenKind-Interpolated, r=petrochenkov Remove `Nonterminal` and `TokenKind::Interpolated` A third attempt at this; the first attempt was #96724 and the second was #114647. r? `@ghost`
2025-04-11suggest: remove redundant `$()?`around `vis` fragmentsMakai-6/+38
2025-04-02Impl `Copy` for `Token` and `TokenKind`.Nicholas Nethercote-11/+11
2025-04-02Remove `NtBlock`, `Nonterminal`, and `TokenKind::Interpolated`.Nicholas Nethercote-14/+9
`NtBlock` is the last remaining variant of `Nonterminal`, so once it is gone then `Nonterminal` can be removed as well.
2025-04-02Remove `NtExpr` and `NtLiteral`.Nicholas Nethercote-7/+28
Notes about tests: - tests/ui/rfcs/rfc-2294-if-let-guard/feature-gate.rs: some messages are now duplicated due to repeated parsing. - tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs: ditto. - `tests/ui/proc-macro/macro-rules-derive-cfg.rs`: the diff looks large but the only difference is the insertion of a single invisible-delimited group around a metavar. - `tests/ui/attributes/nonterminal-expansion.rs`: a slight span degradation, somehow related to the recent massive attr parsing rewrite (#135726). I couldn't work out exactly what is going wrong, but I don't think it's worth holding things up for a single slightly suboptimal error message.
2025-03-19Allow builtin macros to be used more than once.Mara Bos-2/+3
This removes E0773 "A builtin-macro was defined more than once."