about summary refs log tree commit diff
path: root/compiler/rustc_expand/src/expand.rs
AgeCommit message (Collapse)AuthorLines
2025-08-01tiny cleanupEsteban Küber-4/+2
2025-08-01remove recursive search for itemsEsteban Küber-33/+15
2025-08-01Limit how deep we visit items to find cfg'd out namesEsteban Küber-3/+12
2025-08-01Detect more `cfg`d out items in resolution errorsEsteban Küber-14/+24
Use a visitor to collect *all* items (including those nested) that were stripped behind a `cfg` condition. ``` error[E0425]: cannot find function `f` in this scope --> $DIR/nested-cfg-attrs.rs:4:13 | LL | fn main() { f() } | ^ not found in this scope | note: found an item that was configured out --> $DIR/nested-cfg-attrs.rs:2:4 | LL | fn f() {} | ^ note: the item is gated here --> $DIR/nested-cfg-attrs.rs:1:35 | LL | #[cfg_attr(all(), cfg_attr(all(), cfg(FALSE)))] | ^^^^^^^^^^ ```
2025-07-25Stop compilation if macro expansion failedGuillaume Gomez-3/+3
2025-07-15Fix ice for feature-gated cfg attributes applied to the crateJonathan Brouwer-2/+2
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
2025-07-15Define attribute parser & config evaluatorJonathan Brouwer-18/+20
2025-06-25Don't give APITs names with macro expansion placeholder fragments in itMichael Goulet-0/+10
2025-06-22Auto merge of #142706 - fee1-dead-contrib:push-zsznlqyrzsqo, r=oli-obkbors-6/+6
completely deduplicate `Visitor` and `MutVisitor` r? oli-obk This closes rust-lang/rust#127615. ### Discussion > * Give every `MutVisitor::visit_*` method a corresponding `flat_map_*` method. Not every AST node exists in a location where they can be mapped to multiple instances of themselves. Not every AST node exists in a location where they can be removed from existence (e.g. `filter_map_expr`). I don't think this is doable. > * Give every `MutVisitor::visit_*` method a corresponding `Visitor` method and vice versa The only three remaining method-level asymmetries after this PR are `visit_stmt` and `visit_nested_use_tree` (only on `Visitor`) and `visit_span` (only on `MutVisitor`). `visit_stmt` doesn't seem applicable to `MutVisitor` because `walk_flat_map_stmt_kind` will ask `flat_map_item` / `filter_map_expr` to potentially turn a single `Stmt` to multiple based on what a visitor wants. So only using `flat_map_stmt` seems appropriate. `visit_nested_use_tree` is used for `rustc_resolve` to track stuff. Not useful for `MutVisitor` for now. `visit_span` is currently not used for `MutVisitor` already, it was just kept in case we want to revive rust-lang/rust#127241. cc `@cjgillot` maybe we could remove for now and re-insert later if we find a use-case? It does involve some extra effort to maintain. * Remaining FIXMEs `visit_lifetime` has an extra param for `Visitor` that's not in `MutVisitor`. This is again something only used by `rustc_resolve`. I think we can keep that symmetry for now.
2025-06-21Rollup merge of #142690 - petrochenkov:expnoparam, r=compiler-errorsJana Dönszelmann-46/+46
expand: Remove some unnecessary generic parameters
2025-06-20Use a symbol for `ExpansionConfig::crate_name`.Nicholas Nethercote-5/+5
This avoids some symbol interning and `to_string` conversions.
2025-06-19completely deduplicate `Visitor` and `MutVisitor`Deadbeef-6/+6
2025-06-18expand: Remove some unnecessary generic parametersVadim Petrochenkov-46/+46
2025-06-17Rollup merge of #142371 - fee1-dead-contrib:push-xqlkumzurkus, r=petrochenkovJacob Pratt-17/+18
avoid `&mut P<T>` in `visit_expr` etc methods trying a different way than rust-lang/rust#141636 r? ghost
2025-06-12Introduce `-Zmacro-stats`.Nicholas Nethercote-45/+145
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-12avoid `&mut P<T>` in `visit_expr` etc methodsDeadbeef-17/+18
2025-06-06Rollup merge of #141603 - nnethercote:reduce-P, r=fee1-deadGuillaume Gomez-21/+16
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-30Rollup merge of #141430 - fee1-dead-contrib:push-nmzoprvtsvww, r=petrochenkovMatthias Krüger-30/+69
remove `visit_clobber` and move `DummyAstNode` to `rustc_expand` `visit_clobber` is not really useful except for one niche purpose involving generic code. We should just use the replace logic where we can.
2025-05-29avoid some usages of `&mut P<T>` in AST visitorsDeadbeef-1/+1
2025-05-29remove `visit_clobber` and move `DummyAstNode` to `rustc_expand`Deadbeef-30/+69
`visit_clobber` is not really useful except for one niche purpose involving generic code. We should just use the replace logic where we can.
2025-05-28consider glob imports in cfg suggestionbohan-3/+3
2025-05-27Reduce `P<T>` to a typedef of `Box<T>`.Nicholas Nethercote-21/+16
Keep the `P` constructor function for now, to minimize immediate churn. All the `into_inner` calls are removed, which is nice.
2025-05-08Remove associated type `InvocationCollectorNode::AttrsTy`Nicholas Nethercote-18/+12
It's always equal to `ast::AttrVec`, so just use that directly.
2025-05-03Report the `unsafe_attr_outside_unsafe` lint at the closest nodeUrgau-1/+5
2025-04-22Auto merge of #139897 - nnethercote:rm-OpenDelim-CloseDelim, r=petrochenkovbors-3/+2
Remove `token::{Open,Close}Delim` 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 { ``` r? `@petrochenkov`
2025-04-21Remove `token::{Open,Close}Delim`.Nicholas Nethercote-3/+2
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-17Replace infallible `name_or_empty` methods with fallible `name` methods.Nicholas Nethercote-6/+6
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-10Address review comments.Nicholas Nethercote-1/+1
2025-04-10Rename some `name` variables as `ident`.Nicholas Nethercote-5/+5
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-01Address review comments.Nicholas Nethercote-3/+1
2025-04-01Move `ast::Item::ident` into `ast::ItemKind`.Nicholas Nethercote-5/+8
`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-26expand: Leave traces when expanding `cfg` attributesVadim Petrochenkov-7/+6
2025-03-25Track whether an assoc item is in a trait impl or an inherent implOli Scherer-15/+86
2025-03-21expand: Do not report `cfg_attr` traces on macros as unused attributesVadim Petrochenkov-1/+1
2025-03-11Keep items around even if builtin macros on them fail to parseOli Scherer-2/+2
2025-03-01Implment `#[cfg]` and `#[cfg_attr]` in `where` clausesFrank King-3/+35
2025-02-03tree-wide: parallel: Fully removed all `Lrc`, replaced with `Arc`Askar Safin-3/+3
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-1/+1
2024-12-10Keep track of parse errors in `mod`s and don't emit resolve errors for paths ↵Esteban Küber-13/+19
involving them When we expand a `mod foo;` and parse `foo.rs`, we now track whether that file had an unrecovered parse error that reached the end of the file. If so, we keep that information around. When resolving a path like `foo::bar`, we do not emit any errors for "`bar` not found in `foo`", as we know that the parse error might have caused `bar` to not be parsed and accounted for. When this happens in an existing project, every path referencing `foo` would be an irrelevant compile error. Instead, we now skip emitting anything until `foo.rs` is fixed. Tellingly enough, we didn't have any test for errors caused by `mod` expansion. Fix #97734.
2024-12-08Rollup merge of #133424 - Nadrieril:guard-patterns-parsing, r=fee1-deadMatthias Krüger-1/+1
Parse guard patterns This implements the parsing of [RFC3637 Guard Patterns](https://rust-lang.github.io/rfcs/3637-guard-patterns.html) (see also [tracking issue](https://github.com/rust-lang/rust/issues/129967)). This PR is extracted from https://github.com/rust-lang/rust/pull/129996 with minor modifications. cc `@max-niederman`
2024-12-02Change `AttrArgs::Eq` into a struct variantOli Scherer-1/+1
2024-11-24parse guard patternsNadrieril-1/+1
Co-authored-by: Max Niederman <max@maxniederman.com>
2024-11-24refactor pat parser method names/doc-comments to agree with RFC 3637Max Niederman-1/+1
2024-11-20Itemsmaxcabrajac-1/+1
2024-11-15Add WalkItemKind::Ctxt so AssocCtxt is not sent to non-Assoc ItemKindsmaxcabrajac-2/+2
2024-10-28Tweak `expand_incomplete_parse` warning.Nicholas Nethercote-2/+3
By using `token_descr`, as is done for many other errors, we can get slightly better descriptions in error messages, e.g. "macro expansion ignores token `let` and any following" becomes "macro expansion ignores keyword `let` and any tokens following". This will be more important once invisible delimiters start being mentioned in error messages -- without this commit, that leads to error messages such as "error at ``" because invisible delimiters are pretty printed as an empty string.
2024-10-23nightly feature tracking: get rid of the per-feature bool fieldsRalf Jung-2/+2
2024-10-07Rename nested_meta to meta_item_innercodemountains-1/+1
2024-10-06Rename NestedMetaItem to MetaItemInnercodemountains-2/+2