about summary refs log tree commit diff
path: root/src/tools/rustfmt
AgeCommit message (Collapse)AuthorLines
2025-04-03Tighten up assignment operator representations.Nicholas Nethercote-1/+1
In the AST, currently we use `BinOpKind` within `ExprKind::AssignOp` and `AssocOp::AssignOp`, even though this allows some nonsensical combinations. E.g. there is no `&&=` operator. Likewise for HIR and THIR. This commit introduces `AssignOpKind` which only includes the ten assignable operators, and uses it in `ExprKind::AssignOp` and `AssocOp::AssignOp`. (And does similar things for `hir::ExprKind` and `thir::ExprKind`.) This avoids the possibility of nonsensical combinations, as seen by the removal of the `bug!` case in `lang_item_for_binop`. The commit is mostly plumbing, including: - Adds an `impl From<AssignOpKind> for BinOpKind` (AST) and `impl From<AssignOp> for BinOp` (MIR/THIR). - `BinOpCategory` can now be created from both `BinOpKind` and `AssignOpKind`. - Replaces the `IsAssign` type with `Op`, which has more information and a few methods. - `suggest_swapping_lhs_and_rhs`: moves the condition to the call site, it's easier that way. - `check_expr_inner`: had to factor out some code into a separate method. I'm on the fence about whether avoiding the nonsensical combinations is worth the extra code.
2025-04-01Auto merge of #138492 - lcnr:rm-inline_const_pat, r=oli-obkbors-2/+2
remove `feature(inline_const_pat)` Summarizing https://rust-lang.zulipchat.com/#narrow/channel/144729-t-types/topic/remove.20feature.28inline_const_pat.29.20and.20shared.20borrowck. With https://github.com/rust-lang/types-team/issues/129 we will start to borrowck items together with their typeck parent. This is necessary to correctly support opaque types, blocking the new solver and TAIT/ATPIT stabilization with the old one. This means that we cannot really support `inline_const_pat` as they are implemented right now: - we want to typeck inline consts together with their parent body to allow inference to flow both ways and to allow the const to refer to local regions of its parent.This means we also need to borrowck the inline const together with its parent as that's necessary to properly support opaque types - we want the inline const pattern to participate in exhaustiveness checking - to participate in exhaustiveness checking we need to evaluate it, which requires borrowck, which now relies on borrowck of the typeck root, which ends up checking exhaustiveness again. **This is a query cycle**. There are 4 possible ways to handle this: - stop typechecking inline const patterns together with their parent - causes inline const patterns to be different than inline const exprs - prevents bidirectional inference, we need to either fail to compile `if let const { 1 } = 1u32` or `if let const { 1u32 } = 1` - region inference for inline consts will be harder, it feels non-trivial to support inline consts referencing local regions from the parent fn - inline consts no longer participate in exhaustiveness checking. Treat them like `pat if pat == const { .. }` instead. We then only evaluate them after borrowck - difference between `const { 1 }` and `const FOO: usize = 1; match x { FOO => () }`. This is confusing - do they carry their weight if they are now just equivalent to using an if-guard - delay exhaustiveness checking until after borrowck - should be possible in theory, but is a quite involved change and may have some unexpected challenges - remove this feature for now I believe we should either delay exhaustiveness checking or remove the feature entirely. As moving exhaustiveness checking to after borrow checking is quite complex I think the right course of action is to fully remove the feature for now and to add it again once/if we've got that implementation figured out. `const { .. }`-expressions remain stable. These seem to have been the main motivation for https://github.com/rust-lang/rfcs/issues/2920. r? types cc `@rust-lang/types` `@rust-lang/lang` #76001
2025-04-01Address review comments.Nicholas Nethercote-1/+1
2025-04-01Move `ast::Item::ident` into `ast::ItemKind`.Nicholas Nethercote-74/+83
`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-04-01Remove useless `Option<Ident>` arg.Nicholas Nethercote-38/+16
`FmtVisitor::visit_mac` has an `Option<Ident>` arg which is always either `None` or `Some(kw::Empty)`, because `ItemKind::MacCall` always has an empty ident. This value is passed through various functions until it reaches `rewrite_macro_name`, which treats `None` and `Some(kw::Empty)` the same. In other words, the argument is useless. This commit removes it. There is no change in behaviour. The commit also changes a few `symbol::Ident` occurrences to `Ident` in `macros.rs`; `Symbol` is imported in that file so `Ident` might as well be, too. (This is a good example of why it's a bad idea for `Itemt` to have an `ident` field when various item kinds don't have an identifier. It's easy to get confused when "empty identifier" is used to mean "no identifier". This will be fixed in a subsequent commit.)
2025-04-01Simplify `ItemVisitorKind`.Nicholas Nethercote-30/+41
Instead of putting the item inside it, just pass the ident and visibility (the only things needed) alongside it where necessary. This helps with the next commit, which will move the ident's location. Specifically, it gets rid of the `match visitor_kind` in `rewrite_type_alias`.
2025-03-26Rollup merge of #138898 - fmease:decrustify-parser-post-ty-ascr, ↵Stuart Cook-2/+0
r=compiler-errors Mostly parser: Eliminate code that's been dead / semi-dead since the removal of type ascription syntax **Disclaimer**: This PR is intended to mostly clean up code as opposed to bringing about behavioral changes. Therefore it doesn't aim to address any of the 'FIXME: remove after a month [dated: 2023-05-02]: "type ascription syntax has been removed, see issue [#]101728"'. --- By commit: 1. Removes truly dead code: * Since 1.71 (#109128) `let _ = { f: x };` is a syntax error as opposed to a semantic error which allows the parse-time diagnostic (suggestion) "*struct literal body without path // you might have forgotten […]*" to kick in. * The analysis-time diagnostic (suggestion) from <=1.70 "*cannot find value \`f\` in this scope // you might have forgotten […]*" is therefore no longer reachable. 2. Updates `is_certainly_not_a_block` to be in line with the current grammar: * The seq. `{ ident:` is definitely not the start of a block. Before the removal of ty ascr, `{ ident: ty_start` would begin a block expr. * This shouldn't make more code compile IINM, it should *ultimately* only affect diagnostics. * For example, `if T { f: () } {}` will now be interpreted as an `if` with struct lit `T { f: () }` as its *condition* (which is banned in the parser anyway) as opposed to just `T` (with the *consequent* being `f : ()` which is also invalid (since 1.71)). The diagnostics are almost the same because we have two separate parse recovery procedures + diagnostics: `StructLiteralNeedingParens` (*invalid struct lit*) before and `StructLiteralNotAllowedHere` (*struct lits aren't allowed here*) now, as you can see from the diff. * (As an aside, even before this PR, fn `maybe_suggest_struct_literal` should've just used the much older & clearer `StructLiteralNotAllowedHere`) * NB: This does sadly regress the compiler output for `tests/ui/parser/type-ascription-in-pattern.rs` but that can be fixed in follow-up PRs. It's not super important IMO and a natural consequence. 3. Removes code that's become dead due to the prior commit. * Basically reverts #106620 + #112475 (without regressing rustc's output!). * Now the older & more robust parse recovery procedure (cc `StructLiteralNotAllowedHere`) takes care of the cases the removed code used to handle. * This automatically fixes the suggestions for \[[playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=7e2030163b11ee96d17adc3325b01780)\]: * `if Ty::<i32> { f: K }.m() {}`: `if Ty::<i32> { SomeStruct { f: K } }.m() {}` (broken) → ` if (Ty::<i32> { f: K }).m() {}` * `if <T as Trait>::Out { f: K::<> }.m() {}`: `if <T as Trait>(::Out { f: K::<> }).m() {}` (broken) → `if (<T as Trait>::Out { f: K::<> }).m() {}` 4. Merge and simplify UI tests pertaining to this issue, so it's easier to add more regression tests like for the two cases mentioned above. 5. Merge UI tests and add the two regression tests. Best reviewed commit by commit (on request I'll partially squash after approval).
2025-03-25Rollup merge of #138929 - oli-obk:assoc-ctxt-of-trait, r=compiler-errorsMatthias Krüger-1/+2
Visitors track whether an assoc item is in a trait impl or an inherent impl `AssocCtxt::Impl` now contains an `of_trait` field. This allows ast lowering and nameres to not have to track whether we're in a trait impl or an inherent impl.
2025-03-25Track whether an assoc item is in a trait impl or an inherent implOli Scherer-1/+2
2025-03-24Remove fields that are dead since the removal of type ascription syntaxLeón Orell Valerian Liehr-2/+0
Since `{ ident: ident }` is a parse error, these fields are dead.
2025-03-24Remove `is_any_keyword` methods.Nicholas Nethercote-1/+1
They're dodgy, covering all the keywords, including weak ones, and edition-specific ones without considering the edition. They have a single use in rustfmt. This commit changes that use to `is_reserved_ident`, which is a much more widely used alternative and is good enough, judging by the lack of effect on the test suite.
2025-03-21update rustfmt testlcnr-2/+2
2025-03-18Refactor YieldKind so postfix yield must have an expressionEric Holk-6/+6
2025-03-17Teach rustfmt to handle postfix yieldEric Holk-21/+21
This involved fixing the span when parsing .yield
2025-03-14Teach rustfmt to handle postfix yieldEric Holk-2/+30
2025-03-14Preserve yield position during pretty printingEric Holk-2/+2
2025-03-07Rollup merge of #134797 - spastorino:ergonomic-ref-counting-1, r=nikomatsakisMatthias Krüger-0/+5
Ergonomic ref counting This is an experimental first version of ergonomic ref counting. This first version implements most of the RFC but doesn't implement any of the optimizations. This was left for following iterations. RFC: https://github.com/rust-lang/rfcs/pull/3680 Tracking issue: https://github.com/rust-lang/rust/issues/132290 Project goal: https://github.com/rust-lang/rust-project-goals/issues/107 r? ```@nikomatsakis```
2025-03-06Fix rustfmtSantiago Pastorino-0/+5
2025-03-05Simplify `rewrite_explicit_self`Frank King-67/+31
2025-03-05Implement `&pin const self` and `&pin mut self` sugarsFrank King-0/+46
2025-03-04Auto merge of #137959 - matthiaskrgr:rollup-62vjvwr, r=matthiaskrgrbors-8/+26
Rollup of 12 pull requests Successful merges: - #135767 (Future incompatibility warning `unsupported_fn_ptr_calling_conventions`: Also warn in dependencies) - #137852 (Remove layouting dead code for non-array SIMD types.) - #137863 (Fix pretty printing of unsafe binders) - #137882 (do not build additional stage on compiler paths) - #137894 (Revert "store ScalarPair via memset when one side is undef and the other side can be memset") - #137902 (Make `ast::TokenKind` more like `lexer::TokenKind`) - #137921 (Subtree update of `rust-analyzer`) - #137922 (A few cleanups after the removal of `cfg(not(parallel))`) - #137939 (fix order on shl impl) - #137946 (Fix docker run-local docs) - #137955 (Always allow rustdoc-json tests to contain long lines) - #137958 (triagebot.toml: Don't label `test/rustdoc-json` as A-rustdoc-search) r? `@ghost` `@rustbot` modify labels: rollup
2025-03-03Rollup merge of #132388 - frank-king:feature/where-cfg, r=petrochenkovMatthias Krüger-7/+151
Implement `#[cfg]` in `where` clauses This PR implements #115590, which supports `#[cfg]` attributes in `where` clauses. The biggest change is, that it adds `AttrsVec` and `NodeId` to the `ast::WherePredicate` and `HirId` to the `hir::WherePredicate`.
2025-03-03Rename `ast::TokenKind::Not` as `ast::TokenKind::Bang`.Nicholas Nethercote-2/+2
For consistency with `rustc_lexer::TokenKind::Bang`, and because other `ast::TokenKind` variants generally have syntactic names instead of semantic names (e.g. `Star` and `DotDot` instead of `Mul` and `Range`).
2025-03-03Replace `ast::TokenKind::BinOp{,Eq}` and remove `BinOpToken`.Nicholas Nethercote-6/+24
`BinOpToken` is badly named, because it only covers the assignable binary ops and excludes comparisons and `&&`/`||`. Its use in `ast::TokenKind` does allow a small amount of code sharing, but it's a clumsy factoring. This commit removes `ast::TokenKind::BinOp{,Eq}`, replacing each one with 10 individual variants. This makes `ast::TokenKind` more similar to `rustc_lexer::TokenKind`, which has individual variants for all operators. Although the number of lines of code increases, the number of chars decreases due to the frequent use of shorter names like `token::Plus` instead of `token::BinOp(BinOpToken::Plus)`.
2025-03-01Implment `#[cfg]` and `#[cfg_attr]` in `where` clausesFrank King-7/+151
2025-02-28Do not yeet unsafe<> from typeMichael Goulet-1/+10
2025-02-11Add a TyPat in the AST to reuse the generic arg lowering logicOli Scherer-39/+66
2025-02-03tree-wide: parallel: Fully removed all `Lrc`, replaced with `Arc`Askar Safin-57/+57
2025-02-02Use fallback fluent bundle from inner emitter in SilentEmitterbjorn3-12/+2
2025-02-02Slightly simplify DiagCtxt::make_silentbjorn3-1/+1
2025-01-30Disable overflow_delimited_expr in edition 2024Michael Goulet-37/+51
2025-01-28Refactor FnKind variant to hold &FnCelina G. Val-11/+21
2025-01-09Only treat plain literal patterns as shortOli Scherer-12/+43
2025-01-08Rename PatKind::Lit to ExprOli Scherer-3/+3
2025-01-07rustfmt: drop nightly-gating of the `--style-edition` flag registration许杰友 Jieyou Xu (Joe)-6/+6
2024-12-31Stabilize style_edition 2024 in-treeMichael Goulet-10/+6
2024-12-22Make sure we don't lose default struct value when formatting structMichael Goulet-0/+42
2024-12-19Speed up `Parser::expected_token_types`.Nicholas Nethercote-16/+17
The parser pushes a `TokenType` to `Parser::expected_token_types` on every call to the various `check`/`eat` methods, and clears it on every call to `bump`. Some of those `TokenType` values are full tokens that require cloning and dropping. This is a *lot* of work for something that is only used in error messages and it accounts for a significant fraction of parsing execution time. This commit overhauls `TokenType` so that `Parser::expected_token_types` can be implemented as a bitset. This requires changing `TokenType` to a C-style parameterless enum, and adding `TokenTypeSet` which uses a `u128` for the bits. (The new `TokenType` has 105 variants.) The new types `ExpTokenPair` and `ExpKeywordPair` are now arguments to the `check`/`eat` methods. This is for maximum speed. The elements in the pairs are always statically known; e.g. a `token::BinOp(token::Star)` is always paired with a `TokenType::Star`. So we now compute `TokenType`s in advance and pass them in to `check`/`eat` rather than the current approach of constructing them on insertion into `expected_token_types`. Values of these pair types can be produced by the new `exp!` macro, which is used at every `check`/`eat` call site. The macro is for convenience, allowing any pair to be generated from a single identifier. The ident/keyword filtering in `expected_one_of_not_found` is no longer necessary. It was there to account for some sloppiness in `TokenKind`/`TokenType` comparisons. The existing `TokenType` is moved to a new file `token_type.rs`, and all its new infrastructure is added to that file. There is more boilerplate code than I would like, but I can't see how to make it shorter.
2024-12-18Rollup merge of #134253 - nnethercote:overhaul-keywords, r=petrochenkov许杰友 Jieyou Xu (Joe)-75/+12
Overhaul keyword handling The compiler's list of keywords has some problems. - It contains several items that aren't keywords. - The order isn't quite right in a couple of places. - Some of the names of predicates relating to keywords are confusing. - rustdoc and rustfmt have their own (incorrect) versions of the keyword list. - `AllKeywords` is unnecessarily complex. r? ```@jieyouxu```
2024-12-18Only have one source of truth for keywords.Nicholas Nethercote-75/+12
`rustc_symbol` is the source of truth for keywords. rustdoc has its own implicit definition of keywords, via the `is_doc_keyword`. It (presumably) intends to include all keywords, but it omits `yeet`. rustfmt has its own explicit list of Rust keywords. It also (presumably) intends to include all keywords, but it omits `await`, `builtin`, `gen`, `macro_rules`, `raw`, `reuse`, `safe`, and `yeet`. Also, it does linear searches through this list, which is inefficient. This commit fixes all of the above problems by introducing a new predicate `is_any_keyword` in rustc and using it in rustdoc and rustfmt. It documents that it's not the right predicate in most cases.
2024-12-18Rename `RefTokenTreeCursor`.Nicholas Nethercote-15/+15
Because `TokenStreamIter` is a much better name for a `TokenStream` iterator. Also rename the `TokenStream::trees` method as `TokenStream::iter`, and some local variables.
2024-12-18Simplify `RefTokenTreeCursor::look_ahead`.Nicholas Nethercote-2/+2
It's only ever used with a lookahead of 0, so this commit removes the lookahead and renames it `peek`.
2024-12-18Change the lookahead in `MacroParser::new`.Nicholas Nethercote-1/+1
As it happens, lookahead values of 0, 1, and 2 all work fine here, due to the structure of the code. (Values or 3 or greater cause test failures.) This commit changes the lookahead to zero because that will facilitate cleanups in subsequent commits.
2024-12-13Rollup merge of #134140 - compiler-errors:unsafe-binders-ast, r=oli-obkMatthias Krüger-1/+48
Add AST support for unsafe binders I'm splitting up #130514 into pieces. It's impossible for me to keep up with a huge PR like that. I'll land type system support for this next, probably w/o MIR lowering, which will come later. r? `@oli-obk` cc `@BoxyUwU` and `@lcnr` who also may want to look at this, though this PR doesn't do too much yet
2024-12-12Fix toolsMichael Goulet-1/+48
2024-12-10Keep track of parse errors in `mod`s and don't emit resolve errors for paths ↵Esteban Küber-6/+5
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-09Auto merge of #134052 - matthiaskrgr:rollup-puxwqrk, r=matthiaskrgrbors-12/+17
Rollup of 7 pull requests Successful merges: - #133567 (A bunch of cleanups) - #133789 (Add doc alias 'then_with' for `then` method on `bool`) - #133880 (Expand home_dir docs) - #134036 (crash tests: use individual mir opts instead of mir-opt-level where easily possible) - #134045 (Fix some triagebot mentions paths) - #134046 (Remove ignored tests for hangs w/ new solver) - #134050 (Miri subtree update) r? `@ghost` `@rustbot` modify labels: rollup
2024-12-08Rollup merge of #133424 - Nadrieril:guard-patterns-parsing, r=fee1-deadMatthias Krüger-2/+16
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-06Store a single copy of the error registry in DiagCtxtbjorn3-12/+17
And pass this to the individual emitters when necessary.
2024-11-25Refactor `where` predicates, and reserve for attributes supportFrank King-11/+6