about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser/stmt.rs
AgeCommit message (Collapse)AuthorLines
2024-03-21Use better variable names in some `maybe_whole!` calls.Nicholas Nethercote-2/+2
2024-03-21Use `maybe_whole!` to streamline `parse_stmt_without_recovery`.Nicholas Nethercote-11/+5
2024-03-14Rename `ast::StmtKind::Local` into `ast::StmtKind::Let`Guillaume Gomez-4/+4
2024-03-08Rollup merge of #119365 - nbdd0121:asm-goto, r=AmanieuMatthias Krüger-1/+1
Add asm goto support to `asm!` Tracking issue: #119364 This PR implements asm-goto support, using the syntax described in "future possibilities" section of [RFC2873](https://rust-lang.github.io/rfcs/2873-inline-asm.html#asm-goto). Currently I have only implemented the `label` part, not the `fallthrough` part (i.e. fallthrough is implicit). This doesn't reduce the expressive though, since you can use label-break to get arbitrary control flow or simply set a value and rely on jump threading optimisation to get the desired control flow. I can add that later if deemed necessary. r? ``@Amanieu`` cc ``@ojeda``
2024-03-06Cancel parsing ever made during recoveryclubby789-6/+10
2024-03-05Rename all `ParseSess` variables/fields/lifetimes as `psess`.Nicholas Nethercote-3/+3
Existing names for values of this type are `sess`, `parse_sess`, `parse_session`, and `ps`. `sess` is particularly annoying because that's also used for `Session` values, which are often co-located, and it can be difficult to know which type a value named `sess` refers to. (That annoyance is the main motivation for this change.) `psess` is nice and short, which is good for a name used this much. The commit also renames some `parse_sess_created` values as `psess_created`.
2024-03-01Detect more cases of `=` to `:` typoEsteban Küber-10/+64
When a `Local` is fully parsed, but not followed by a `;`, keep the `:` span arround and mention it. If the type could continue being parsed as an expression, suggest replacing the `:` with a `=`. ``` error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.` --> file.rs:2:32 | 2 | let _: std::env::temp_dir().join("foo"); | - ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=` | | | while parsing the type for `_` | help: use `=` if you meant to assign ``` Fix #119665.
2024-02-28Rename `DiagnosticBuilder` as `Diag`.Nicholas Nethercote-5/+2
Much better! Note that this involves renaming (and updating the value of) `DIAGNOSTIC_BUILDER` in clippy.
2024-02-27Refactor `take_for_recovery` call sites.Nicholas Nethercote-2/+1
To make them more concise and similar to each other.
2024-02-25Add `ErrorGuaranteed` to `ast::ExprKind::Err`Lieselotte-28/+36
2024-02-24Add asm label support to AST and HIRGary Guo-1/+1
2024-02-20Add newtype for parser recoveryclubby789-3/+3
2024-02-20Add newtype for raw identsclubby789-1/+1
2024-01-18Suggest wrapping mac args in parens rather than the whole expressionMichael Goulet-4/+11
2024-01-08Make `DiagnosticBuilder::emit` consuming.Nicholas Nethercote-3/+3
This works for most of its call sites. This is nice, because `emit` very much makes sense as a consuming operation -- indeed, `DiagnosticBuilderState` exists to ensure no diagnostic is emitted twice, but it uses runtime checks. For the small number of call sites where a consuming emit doesn't work, the commit adds `DiagnosticBuilder::emit_without_consuming`. (This will be removed in subsequent commits.) Likewise, `emit_unless` becomes consuming. And `delay_as_bug` becomes consuming, while `delay_as_bug_without_consuming` is added (which will also be removed in subsequent commits.) All this requires significant changes to `DiagnosticBuilder`'s chaining methods. Currently `DiagnosticBuilder` method chaining uses a non-consuming `&mut self -> &mut Self` style, which allows chaining to be used when the chain ends in `emit()`, like so: ``` struct_err(msg).span(span).emit(); ``` But it doesn't work when producing a `DiagnosticBuilder` value, requiring this: ``` let mut err = self.struct_err(msg); err.span(span); err ``` This style of chaining won't work with consuming `emit` though. For that, we need to use to a `self -> Self` style. That also would allow `DiagnosticBuilder` production to be chained, e.g.: ``` self.struct_err(msg).span(span) ``` However, removing the `&mut self -> &mut Self` style would require that individual modifications of a `DiagnosticBuilder` go from this: ``` err.span(span); ``` to this: ``` err = err.span(span); ``` There are *many* such places. I have a high tolerance for tedious refactorings, but even I gave up after a long time trying to convert them all. Instead, this commit has it both ways: the existing `&mut self -> Self` chaining methods are kept, and new `self -> Self` chaining methods are added, all of which have a `_mv` suffix (short for "move"). Changes to the existing `forward!` macro lets this happen with very little additional boilerplate code. I chose to add the suffix to the new chaining methods rather than the existing ones, because the number of changes required is much smaller that way. This doubled chainging is a bit clumsy, but I think it is worthwhile because it allows a *lot* of good things to subsequently happen. In this commit, there are many `mut` qualifiers removed in places where diagnostics are emitted without being modified. In subsequent commits: - chaining can be used more, making the code more concise; - more use of chaining also permits the removal of redundant diagnostic APIs like `struct_err_with_code`, which can be replaced easily with `struct_err` + `code_mv`; - `emit_without_diagnostic` can be removed, which simplifies a lot of machinery, removing the need for `DiagnosticBuilderState`.
2023-12-24Remove `ParseSess` methods that duplicate `DiagCtxt` methods.Nicholas Nethercote-10/+11
Also add missing `#[track_caller]` attributes to `DiagCtxt` methods as necessary to keep tests working.
2023-12-24Remove `Parser` methods that duplicate `DiagCtxt` methods.Nicholas Nethercote-1/+1
2023-12-23Give `DiagnosticBuilder` a default type.Nicholas Nethercote-2/+2
`IntoDiagnostic` defaults to `ErrorGuaranteed`, because errors are the most common diagnostic level. It makes sense to do likewise for the closely-related (and much more widely used) `DiagnosticBuilder` type, letting us write `DiagnosticBuilder<'a, ErrorGuaranteed>` as just `DiagnosticBuilder<'a>`. This cuts over 200 lines of code due to many multi-line things becoming single line things.
2023-11-29Rollup merge of #118394 - nnethercote:rm-hir-Ops, r=cjgillotMatthias Krüger-2/+2
Remove HIR opkinds `hir::BinOp`, `hir::BinOpKind`, and `hir::UnOp` are identical to `ast::BinOp`, `ast::BinOpKind`, and `ast::UnOp`, respectively. This seems silly, so this PR removes the HIR ones. (A re-export lets the AST ones be referred to using a `hir::` qualifier, which avoids renaming churn.) r? `@cjgillot`
2023-11-28Rename `BinOpKind::lazy` as `BinOpKind::is_lazy`.Nicholas Nethercote-1/+1
To match `BinOpKind::is_comparison` and `hir::BinOpKind::is_lazy`.
2023-11-28Rework `ast::BinOpKind::to_string` and `ast::UnOp::to_string`.Nicholas Nethercote-1/+1
- Rename them both `as_str`, which is the typical name for a function that returns a `&str`. (`to_string` is appropriate for functions returning `String` or maybe `Cow<'a, str>`.) - Change `UnOp::as_str` from an associated function (weird!) to a method. - Avoid needless `self` dereferences.
2023-11-27Change help message to make some sense in broader contextHirochika Matsumoto-1/+1
2023-11-27Address review feedbacksHirochika Matsumoto-16/+17
Also addressed merge conflicts upon rebasing.
2023-11-27Make tidy test happyHirochika Matsumoto-1/+1
2023-11-27Detect Python-like slicing and suggest how to fixHirochika Matsumoto-0/+16
Fix #108215
2023-11-19Rollup merge of #117988 - estebank:issue-106020, r=cjgillotMichael Goulet-0/+14
Handle attempts to have multiple `cfg`d tail expressions When encountering code that seems like it might be trying to have multiple tail expressions depending on `cfg` information, suggest alternatives that will success to parse. ```rust fn foo() -> String { #[cfg(feature = "validation")] [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>() #[cfg(not(feature = "validation"))] String::new() } ``` ``` error: expected `;`, found `#` --> $DIR/multiple-tail-expr-behind-cfg.rs:5:64 | LL | #[cfg(feature = "validation")] | ------------------------------ only `;` terminated statements or tail expressions are allowed after this attribute LL | [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>() | ^ expected `;` here LL | #[cfg(not(feature = "validation"))] | - unexpected token | help: add `;` here | LL | [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>(); | + help: alternatively, consider surrounding the expression with a block | LL | { [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>() } | + + help: it seems like you are trying to provide different expressions depending on `cfg`, consider using `if cfg!(..)` | LL ~ if cfg!(feature = "validation") { LL ~ [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>() LL ~ } else if cfg!(not(feature = "validation")) { LL ~ String::new() LL + } | ``` Fix #106020. r? `@oli-obk`
2023-11-16Handle attempts to have multiple `cfg`d tail expressionsEsteban Küber-0/+14
When encountering code that seems like it might be trying to have multiple tail expressions depending on `cfg` information, suggest alternatives that will success to parse. ```rust fn foo() -> String { #[cfg(feature = "validation")] [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>() #[cfg(not(feature = "validation"))] String::new() } ``` ``` error: expected `;`, found `#` --> $DIR/multiple-tail-expr-behind-cfg.rs:5:64 | LL | #[cfg(feature = "validation")] | ------------------------------ only `;` terminated statements or tail expressions are allowed after this attribute LL | [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>() | ^ expected `;` here LL | #[cfg(not(feature = "validation"))] | - unexpected token | help: add `;` here | LL | [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>(); | + help: alternatively, consider surrounding the expression with a block | LL | { [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>() } | + + help: it seems like you are trying to provide different expressions depending on `cfg`, consider using `if cfg!(..)` | LL ~ if cfg!(feature = "validation") { LL ~ [1, 2, 3].iter().map(|c| c.to_string()).collect::<String>() LL ~ } else if cfg!(not(feature = "validation")) { LL ~ String::new() LL + } | ``` Fix #106020.
2023-11-16More detail when expecting expression but encountering bad macro argumentEsteban Küber-1/+1
Partially address #71039.
2023-11-02Minimize `pub` usage in `source_map.rs`.Nicholas Nethercote-1/+1
Most notably, this commit changes the `pub use crate::*;` in that file to `use crate::*;`. This requires a lot of `use` items in other crates to be adjusted, because everything defined within `rustc_span::*` was also available via `rustc_span::source_map::*`, which is bizarre. The commit also removes `SourceMap::span_to_relative_line_string`, which is unused.
2023-10-20Move where doc comment meant as comment checkEsteban Küber-17/+0
The new place makes more sense and covers more cases beyond individual statements. ``` error: expected one of `.`, `;`, `?`, `else`, or an operator, found doc comment `//!foo --> $DIR/doc-comment-in-stmt.rs:25:22 | LL | let y = x.max(1) //!foo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected one of `.`, `;`, `?`, `else`, or an operator | help: add a space before `!` to write a regular comment | LL | let y = x.max(1) // !foo | + ``` Fix #65329.
2023-10-13Format all the let chains in compilerMichael Goulet-15/+26
2023-08-03Remove `MacDelimiter`.Nicholas Nethercote-2/+1
It's the same as `Delimiter`, minus the `Invisible` variant. I'm generally in favour of using types to make impossible states unrepresentable, but this one feels very low-value, and the conversions between the two types are annoying and confusing. Look at the change in `src/tools/rustfmt/src/expr.rs` for an example: the old code converted from `MacDelimiter` to `Delimiter` and back again, for no good reason. This suggests the author was confused about the types.
2023-07-30inline format!() args up to and including rustc_middleMatthias Krüger-5/+4
2023-05-29Use `Cow` in `{D,Subd}iagnosticMessage`.Nicholas Nethercote-3/+4
Each of `{D,Subd}iagnosticMessage::{Str,Eager}` has a comment: ``` // FIXME(davidtwco): can a `Cow<'static, str>` be used here? ``` This commit answers that question in the affirmative. It's not the most compelling change ever, but it might be worth merging. This requires changing the `impl<'a> From<&'a str>` impls to `impl From<&'static str>`, which involves a bunch of knock-on changes that require/result in call sites being a little more precise about exactly what kind of string they use to create errors, and not just `&str`. This will result in fewer unnecessary allocations, though this will not have any notable perf effects given that these are error paths. Note that I was lazy within Clippy, using `to_string` in a few places to preserve the existing string imprecision. I could have used `impl Into<{D,Subd}iagnosticMessage>` in various places as is done in the compiler, but that would have required changes to *many* call sites (mostly changing `&format("...")` to `format!("...")`) which didn't seem worthwhile.
2023-05-18Rollup merge of #111054 - cjgillot:cfg-eval-recover, r=b-naberDylan DPC-1/+2
Do not recover when parsing stmt in cfg-eval. `parse_stmt` does recovery on its own. When parsing the statement fails, we always get `Ok(None)` instead of an `Err` variant with the diagnostic that we can emit. To avoid this behaviour, we need to opt-out of recovery for cfg_eval. Fixes https://github.com/rust-lang/rust/issues/105228
2023-05-09Rollup merge of #111120 - chenyukang:yukang-suggest-let, r=NilstriebDylan DPC-10/+7
Suggest let for possible binding with ty Origin from https://github.com/rust-lang/rust/pull/109128#discussion_r1179866137 r? `@Nilstrieb`
2023-05-08code refactor and fix wrong suggestionyukang-1/+7
2023-05-08Suggest let for possible binding with tyyukang-9/+0
2023-05-05Add parsing for builtin # in expression and item contextest31-1/+5
2023-05-03Restrict `From<S>` for `{D,Subd}iagnosticMessage`.Nicholas Nethercote-1/+1
Currently a `{D,Subd}iagnosticMessage` can be created from any type that impls `Into<String>`. That includes `&str`, `String`, and `Cow<'static, str>`, which are reasonable. It also includes `&String`, which is pretty weird, and results in many places making unnecessary allocations for patterns like this: ``` self.fatal(&format!(...)) ``` This creates a string with `format!`, takes a reference, passes the reference to `fatal`, which does an `into()`, which clones the reference, doing a second allocation. Two allocations for a single string, bleh. This commit changes the `From` impls so that you can only create a `{D,Subd}iagnosticMessage` from `&str`, `String`, or `Cow<'static, str>`. This requires changing all the places that currently create one from a `&String`. Most of these are of the `&format!(...)` form described above; each one removes an unnecessary static `&`, plus an allocation when executed. There are also a few places where the existing use of `&String` was more reasonable; these now just use `clone()` at the call site. As well as making the code nicer and more efficient, this is a step towards possibly using `Cow<'static, str>` in `{D,Subd}iagnosticMessage::{Str,Eager}`. That would require changing the `From<&'a str>` impls to `From<&'static str>`, which is doable, but I'm not yet sure if it's worthwhile.
2023-05-01Do not recover when parsing stmt in cfg-eval.Camille GILLOT-1/+2
2023-05-01soften the wording for removing type ascriptionyukang-2/+2
2023-05-01Rip it outNilstrieb-20/+107
My type ascription Oh rip it out Ah If you think we live too much then You can sacrifice diagnostics Don't mix your garbage Into my syntax So many weird hacks keep diagnostics alive Yet I don't even step outside So many bad diagnostics keep tyasc alive Yet tyasc doesn't even bother to survive!
2023-03-09feat/refactor: improve errors in case of ident with number at startEzra Shaw-12/+0
2023-02-24Replace parse_[sth]_expr with parse_expr_[sth] function namesest31-5/+5
This resolves an inconsistency in naming style for functions on the parser, between functions parsing specific kinds of items and those for expressions, favoring the parse_item_[sth] style used by functions for items. There are multiple advantages of that style: * functions of both categories are collected in the same place in the rustdoc output. * it helps with autocompletion, as you can narrow down your search for a function to those about expressions. * it mirrors rust's path syntax where less specific things come first, then it gets more specific, i.e. std::collections::hash_map::Entry The disadvantage is that it doesn't "read like a sentence" any more, but I think the advantages weigh more greatly. This change was mostly application of this command: sed -i -E 's/(fn |\.)parse_([[:alnum:]_]+)_expr/\1parse_expr_\2/' compiler/rustc_parse/src/parser/*.rs Plus very minor fixes outside of rustc_parse, and an invocation of x fmt.
2023-02-21Use `ThinVec` in `ast::Block`.Nicholas Nethercote-4/+9
2023-02-05rustc_parse: remove huge error importsest31-23/+23
2023-02-01rustc_parse: migrate more to diagnostic structsXiretza-2/+3
2023-01-30Replace enum `==`s with `match`es where it makes senseMaybe Waffle-11/+11
2023-01-14Make `LhsExpr::AlreadyParsed` a named structMaybe Waffle-2/+8