summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser
AgeCommit message (Collapse)AuthorLines
2025-01-25Only assert the `Parser` size on specific archesJosh Stone-2/+3
The size of this struct depends on the alignment of `u128`, for example powerpc64le and s390x have align-8 and end up with only 280 bytes. Our 64-bit tier-1 arches are the same though, so let's just assert on those. (cherry picked from commit aef640a6130ccb3edf9bc720881c3a9dde3c0ecd)
2024-12-29Rollup merge of #134884 - calciumbe:patch1, r=jieyouxuMatthias Krüger-1/+1
Fix typos Hello, I fix some typos in docs and comments. Thank you very much.
2024-12-29fix: typoscalciumbe-1/+1
Signed-off-by: calciumbe <192480234+calciumbe@users.noreply.github.com>
2024-12-27Skip parenthesis around tuple struct field callsDavid Tolnay-1/+1
2024-12-21Rollup merge of #134600 - dtolnay:chainedcomparison, r=oli-obkJacob Pratt-10/+2
Fix parenthesization of chained comparisons by pretty-printer Example: ```rust macro_rules! repro { () => { 1 < 2 }; } fn main() { let _ = repro!() == false; } ``` Previously `-Zunpretty=expanded` would pretty-print this syntactically invalid output: `fn main() { let _ = 1 < 2 == false; }` ```console error: comparison operators cannot be chained --> <anon>:8:23 | 8 | fn main() { let _ = 1 < 2 == false; } | ^ ^^ | help: parenthesize the comparison | 8 | fn main() { let _ = (1 < 2) == false; } | + + ``` With the fix, it will print `fn main() { let _ = (1 < 2) == false; }`. Making `-Zunpretty=expanded` consistently produce syntactically valid Rust output is important because that is what makes it possible for `cargo expand` to format and perform filtering on the expanded code. ## Review notes According to `rg '\.fixity\(\)' compiler/` the `fixity` function is called only 3 places: - https://github.com/rust-lang/rust/blob/13170cd787cb733ed24842ee825bcbd98dc01476/compiler/rustc_ast_pretty/src/pprust/state/expr.rs#L283-L287 - https://github.com/rust-lang/rust/blob/13170cd787cb733ed24842ee825bcbd98dc01476/compiler/rustc_hir_pretty/src/lib.rs#L1295-L1299 - https://github.com/rust-lang/rust/blob/13170cd787cb733ed24842ee825bcbd98dc01476/compiler/rustc_parse/src/parser/expr.rs#L282-L289 The 2 pretty printers definitely want to treat comparisons using `Fixity::None`. That's the whole bug being fixed. Meanwhile, the parser's `Fixity::None` codepath is previously unreachable as indicated by the comment, so as long as `Fixity::None` here behaves exactly the way that `Fixity::Left` used to behave, you can tell that this PR definitely does not constitute any behavior change for the parser. My guess for why comparison operators were set to `Fixity::Left` instead of `Fixity::None` is that it's a very old workaround for giving a good chained comparisons diagnostic (like what I pasted above). Nowadays that is handled by a different dedicated codepath.
2024-12-21Rollup merge of #133087 - estebank:stmt-misparse, r=chenyukangJacob Pratt-2/+53
Detect missing `.` in method chain in `let` bindings and statements On parse errors where an ident is found where one wasn't expected, see if the next elements might have been meant as method call or field access. ``` error: expected one of `.`, `;`, `?`, `else`, or an operator, found `map` --> $DIR/missing-dot-on-statement-expression.rs:7:29 | LL | let _ = [1, 2, 3].iter()map(|x| x); | ^^^ expected one of `.`, `;`, `?`, `else`, or an operator | help: you might have meant to write a method call | LL | let _ = [1, 2, 3].iter().map(|x| x); | + ```
2024-12-20Change comparison operators to have Fixity::NoneDavid Tolnay-10/+2
2024-12-21Do not suggest `foo.Bar`Esteban Küber-1/+6
2024-12-21Account for missing `.` in macros to avoid incorrect suggestionEsteban Küber-0/+4
2024-12-21Detect missing `.` in method chain in let bindings and statementsEsteban Küber-2/+44
On parse errors where an ident is found where one wasn't expected, see if the next elements might have been meant as method call or field access. ``` error: expected one of `.`, `;`, `?`, `else`, or an operator, found `map` --> $DIR/missing-dot-on-statement-expression.rs:7:29 | LL | let _ = [1, 2, 3].iter()map(|x| x); | ^^^ expected one of `.`, `;`, `?`, `else`, or an operator | help: you might have meant to write a method call | LL | let _ = [1, 2, 3].iter().map(|x| x); | + ```
2024-12-20Reduce the amount of explicit FatalError.raise()bjorn3-14/+6
Instead use dcx.abort_if_error() or guar.raise_fatal() instead. These guarantee that an error actually happened previously and thus we don't silently abort.
2024-12-19Fix `Parser` size assertion on s390x.Nicholas Nethercote-3/+3
For some reason the memory layout is different on s390x.
2024-12-19Make `TokenType::from_u32` foolproof.Nicholas Nethercote-115/+126
Currently it relies on having the right integer for every variant, and if you add a variant you need to adjust the integers for all subsequent variants, which is a pain. This commit introduces a match guard formulation that takes advantage of the enum-to-integer conversion to avoid specifying the integer for each variant. And it does this via a macro to avoid lots of boilerplate.
2024-12-19Speed up `Parser::expected_token_types`.Nicholas Nethercote-704/+1263
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-19Remove `bra`/`ket` naming.Nicholas Nethercote-24/+24
This is a naming convention used in a handful of spots in the parser for delimiters. It confused me when I first saw it a long time ago, and I've never liked it. A web search says "Bra-ket notation" exists in linear algebra but the terminology has zero prior use in a programming context, as far as I can tell. This commit changes it to `open`/`close`, which is consistent with the rest of the compiler.
2024-12-19Tweak some parser `check`/`eat` methods.Nicholas Nethercote-25/+20
The most significant is `check_keyword`: it now only pushes to `expected_token_types` if the keyword check fails, which matches how all the other `check` methods work. The remainder are just tweaks to make these methods more consistent with each other.
2024-12-19Rename `Parser::expected_tokens` as `Parser::expected_token_types`.Nicholas Nethercote-24/+25
Because the `Token` type is similar to but different to the `TokenType` type, and the difference is important, so we want to avoid confusion.
2024-12-18Auto merge of #134443 - joshtriplett:use-field-init-shorthand, ↵bors-1/+1
r=lqd,tgross35,nnethercote Use field init shorthand where possible Field init shorthand allows writing initializers like `tcx: tcx` as `tcx`. The compiler already uses it extensively. Fix the last few places where it isn't yet used. EDIT: this PR also updates `rustfmt.toml` to set `use_field_init_shorthand = true`.
2024-12-18Rollup merge of #134253 - nnethercote:overhaul-keywords, r=petrochenkov许杰友 Jieyou Xu (Joe)-4/+4
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-18Rollup merge of #134161 - nnethercote:overhaul-token-cursors, r=spastorino许杰友 Jieyou Xu (Joe)-42/+72
Overhaul token cursors Some nice cleanups here. r? `````@davidtwco`````
2024-12-18Only have one source of truth for keywords.Nicholas Nethercote-2/+2
`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-18Simplify `AllKeywords`.Nicholas Nethercote-2/+2
It's a verbose reinvention of a range type, and can be cut down a lot.
2024-12-18Re-export more `rustc_span::symbol` things from `rustc_span`.Nicholas Nethercote-25/+16
`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-18Overhaul `TokenTreeCursor`.Nicholas Nethercote-33/+63
- Move it to `rustc_parse`, which is the only crate that uses it. This lets us remove all the `pub` markers from it. - Change `next_ref` and `look_ahead` to `get` and `bump`, which work better for the `rustc_parse` uses. - This requires adding a `TokenStream::get` method, which is simple. - In `TokenCursor`, we currently duplicate the `DelimSpan`/`DelimSpacing`/`Delimiter` from the surrounding `TokenTree::Delimited` in the stack. This isn't necessary so long as we don't prematurely move past the `Delimited`, and is a small perf win on a very hot code path. - In `parse_token_tree`, we clone the relevant `TokenTree::Delimited` instead of constructing an identical one from pieces.
2024-12-18Rename `RefTokenTreeCursor`.Nicholas Nethercote-9/+9
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-17Use field init shorthand where possibleJosh Triplett-1/+1
Field init shorthand allows writing initializers like `tcx: tcx` as `tcx`. The compiler already uses it extensively. Fix the last few places where it isn't yet used.
2024-12-16Rollup merge of #134284 - estebank:issue-74863, r=lcnrMatthias Krüger-2/+2
Keep track of patterns that could have introduced a binding, but didn't When we recover from a pattern parse error, or a pattern uses `..`, we keep track of that and affect resolution error for missing bindings that could have been provided by that pattern. We differentiate between `..` and parse recovery. We silence resolution errors likely caused by the pattern parse error. ``` error[E0425]: cannot find value `title` in this scope --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:18:30 | LL | if let Website { url, .. } = website { | ------------------- this pattern doesn't include `title`, which is available in `Website` LL | println!("[{}]({})", title, url); | ^^^^^ not found in this scope ``` Fix #74863.
2024-12-15Add hir::AttributeJonathan Dönszelmann-7/+6
2024-12-15Rename `value` field to `expr` to simplify later commits' diffsOli Scherer-1/+1
2024-12-13Keep track of patterns that could have introduced a binding, but didn'tEsteban Küber-2/+2
When we recover from a pattern parse error, or a pattern uses `..`, we keep track of that and affect resolution error for missing bindings that could have been provided by that pattern. We differentiate between `..` and parse recovery. We silence resolution errors likely caused by the pattern parse error. ``` error[E0425]: cannot find value `title` in this scope --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:19:30 | LL | println!("[{}]({})", title, url); | ^^^^^ not found in this scope | note: `Website` has a field `title` which could have been included in this pattern, but it wasn't --> $DIR/struct-pattern-with-missing-fields-resolve-error.rs:17:12 | LL | / struct Website { LL | | url: String, LL | | title: Option<String> , | | ----- defined here LL | | } | |_- ... LL | if let Website { url, .. } = website { | ^^^^^^^^^^^^^^^^^^^ this pattern doesn't include `title`, which is available in `Website` ``` Fix #74863.
2024-12-13Rollup merge of #134140 - compiler-errors:unsafe-binders-ast, r=oli-obkMatthias Krüger-3/+39
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-13Rollup merge of #133937 - ↵Matthias Krüger-1/+1
estebank:silence-resolve-errors-from-mod-with-parse-errors, r=davidtwco Keep track of parse errors in `mod`s and don't emit resolve errors for paths 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 in the HIR and mark its `DefId` in the `Resolver`. 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 expansion of `mod`s with parse errors. Fix https://github.com/rust-lang/rust/issues/97734.
2024-12-13Stabilize async closuresMichael Goulet-4/+1
2024-12-12Add testsMichael Goulet-1/+3
2024-12-12Add unwrap_unsafe_binder and wrap_unsafe_binder macro operatorsMichael Goulet-2/+21
2024-12-12Parsing unsafe bindersMichael Goulet-1/+16
2024-12-12Rollup merge of #134187 - nnethercote:rm-PErr, r=jieyouxuMatthias Krüger-3/+3
Remove `PErr`. It's just a synonym for `Diag` that adds no value and is only used in a few places. r? ``@spastorino``
2024-12-12Rollup merge of #134173 - onur-ozkan:allow-symbol-intern-string-literal, ↵Matthias Krüger-0/+4
r=jieyouxu allow `symbol_intern_string_literal` lint in test modules Since #133545, `x check compiler --stage 1` no longer works because compiler test modules trigger `symbol_intern_string_literal` lint errors. Bootstrap shouldn't control when to ignore or enable this lint in the compiler tree (using `Kind != Test` was ineffective for obvious reasons). Also, conditionally adding this rustflag invalidates the build cache between `x test` and other commands. This PR removes the `Kind` check from bootstrap and handles it directly in the compiler tree in a more natural way.
2024-12-12Remove `PErr`.Nicholas Nethercote-3/+3
It's just a synonym for `Diag` that adds no value and is only used in a few places.
2024-12-11allow `symbol_intern_string_literal` lint in test modulesonur-ozkan-0/+4
Signed-off-by: onur-ozkan <work@onurozkan.dev>
2024-12-11Don't emit "field expressions may not have generic arguments" if it's a ↵Orion Gonzalez-2/+5
method call without ()
2024-12-10Keep track of parse errors in `mod`s and don't emit resolve errors for paths ↵Esteban Küber-1/+1
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-09Detect `struct S(ty = val);`Esteban Küber-1/+17
Emit a specific error for unsupported default field value syntax in tuple structs.
2024-12-09Introduce `default_field_values` featureEsteban Küber-4/+9
Initial implementation of `#[feature(default_field_values]`, proposed in https://github.com/rust-lang/rfcs/pull/3681. Support default fields in enum struct variant Allow default values in an enum struct variant definition: ```rust pub enum Bar { Foo { bar: S = S, baz: i32 = 42 + 3, } } ``` Allow using `..` without a base on an enum struct variant ```rust Bar::Foo { .. } ``` `#[derive(Default)]` doesn't account for these as it is still gating `#[default]` only being allowed on unit variants. Support `#[derive(Default)]` on enum struct variants with all defaulted fields ```rust pub enum Bar { #[default] Foo { bar: S = S, baz: i32 = 42 + 3, } } ``` Check for missing fields in typeck instead of mir_build. Expand test with `const` param case (needs `generic_const_exprs` enabled). Properly instantiate MIR const The following works: ```rust struct S<A> { a: Vec<A> = Vec::new(), } S::<i32> { .. } ``` Add lint for default fields that will always fail const-eval We *allow* this to happen for API writers that might want to rely on users' getting a compile error when using the default field, different to the error that they would get when the field isn't default. We could change this to *always* error instead of being a lint, if we wanted. This will *not* catch errors for partially evaluated consts, like when the expression relies on a const parameter. Suggestions when encountering `Foo { .. }` without `#[feature(default_field_values)]`: - Suggest adding a base expression if there are missing fields. - Suggest enabling the feature if all the missing fields have optional values. - Suggest removing `..` if there are no missing fields.
2024-12-08Rollup merge of #133424 - Nadrieril:guard-patterns-parsing, r=fee1-deadMatthias Krüger-48/+68
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-04Fix suggestion when shorthand self has erroneous typeMichael Goulet-1/+29
2024-12-03Rollup merge of #133545 - clubby789:symbol-intern-lit, r=jieyouxuMatthias Krüger-2/+2
Lint against Symbol::intern on a string literal Disabled in tests where this doesn't make much sense
2024-12-03Rollup merge of #132612 - compiler-errors:async-trait-bounds, r=lcnrMatthias Krüger-2/+2
Gate async fn trait bound modifier on `async_trait_bounds` This PR moves `async Fn()` trait bounds into a new feature gate: `feature(async_trait_bounds)`. The general vibe is that we will most likely stabilize the `feature(async_closure)` *without* the `async Fn()` trait bound modifier, so we need to gate that separately. We're trying to work on the general vision of `async` trait bound modifier general in: https://github.com/rust-lang/rfcs/pull/3710, however that RFC still needs more time for consensus to converge, and we've decided that the value that users get from calling the bound `async Fn()` is *not really* worth blocking landing async closures in general.
2024-12-02Rollup merge of #133746 - oli-obk:push-xwyrylxmrtvq, r=jieyouxuGuillaume Gomez-1/+1
Change `AttrArgs::Eq` to a struct variant Cleanups for simplifying https://github.com/rust-lang/rust/pull/131808 Basically changes `AttrArgs::Eq` to a struct variant and then avoids several matches on `AttrArgsEq` in favor of methods on it. This will make future refactorings simpler, as they can either keep methods or switch to field accesses without having to restructure code
2024-12-02Gate async fn trait bound modifier on async_trait_boundsMichael Goulet-2/+2