summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser/diagnostics.rs
AgeCommit message (Collapse)AuthorLines
2024-01-27Rollup merge of #118182 - estebank:issue-118164, r=davidtwcoMatthias Krüger-2/+17
Properly recover from trailing attr in body When encountering an attribute in a body, we try to recover from an attribute on an expression (as opposed to a statement). We need to properly clean up when the attribute is at the end of the body where a tail expression would be. Fix #118164, fix #118575.
2024-01-26Properly recover from trailing attr in bodyEsteban Küber-2/+17
When encountering an attribute in a body, we try to recover from an attribute on an expression (as opposed to a statement). We need to properly clean up when the attribute is at the end of the body where a tail expression would be. Fix #118164.
2024-01-26Rollup merge of #119342 - sjwang05:issue-112254, r=wesleywiserMatthias Krüger-5/+20
Emit suggestion when trying to write exclusive ranges as `..<` Closes #112254
2024-01-10Rename consuming chaining methods on `DiagnosticBuilder`.Nicholas Nethercote-2/+2
In #119606 I added them and used a `_mv` suffix, but that wasn't great. A `with_` prefix has three different existing uses. - Constructors, e.g. `Vec::with_capacity`. - Wrappers that provide an environment to execute some code, e.g. `with_session_globals`. - Consuming chaining methods, e.g. `Span::with_{lo,hi,ctxt}`. The third case is exactly what we want, so this commit changes `DiagnosticBuilder::foo_mv` to `DiagnosticBuilder::with_foo`. Thanks to @compiler-errors for the suggestion.
2024-01-08Emit suggestion when trying to write exclusive ranges as `..<`sjwang05-5/+20
2024-01-08Remove a fourth `DiagnosticBuilder::emit_without_consuming` call.Nicholas Nethercote-9/+8
The old code was very hard to understand, involving an `emit_without_consuming` call *and* a `delay_as_bug_without_consuming` call. With slight changes both calls can be avoided. Not creating the error until later is crucial, as is the early return in the `if recovered` block. It took me some time to come up with this reworking -- it went through intermediate states much further from the original code than this final version -- and it's isn't obvious at a glance that it is equivalent. But I think it is, and the unchanged test behaviour is good supporting evidence. The commit also changes `check_trailing_angle_brackets` to return `Option<ErrorGuaranteed>`. This provides a stricter proof that it emitted an error message than asserting `dcx.has_errors().is_some()`, which would succeed if any error had previously been emitted anywhere.
2024-01-08Remove a second `DiagnosticBuilder::emit_without_consuming` call.Nicholas Nethercote-11/+6
Instead of taking `seq` as a mutable reference, `maybe_recover_struct_lit_bad_delims` now consumes `seq` on the recovery path, and returns `seq` unchanged on the non-recovery path. The commit also combines an `if` and a `match` to merge two identical paths. Also change `recover_seq_parse_error` so it receives a `PErr` instead of a `PResult`, because all the call sites now handle the `Ok`/`Err` distinction themselves.
2024-01-08Remove a `DiagnosticBuilder::emit_without_consuming` call.Nicholas Nethercote-4/+7
In this parsing recovery function, we only need to emit the previously obtained error message and mark `expr` as erroneous in the case where we actually recover.
2024-01-08Use chaining for `DiagnosticBuilder` construction and `emit`.Nicholas Nethercote-9/+10
To avoid the use of a mutable local variable, and because it reads more nicely.
2024-01-08Make `DiagnosticBuilder::emit` consuming.Nicholas Nethercote-5/+5
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`.
2024-01-03Rename some `Diagnostic` setters.Nicholas Nethercote-2/+2
`Diagnostic` has 40 methods that return `&mut Self` and could be considered setters. Four of them have a `set_` prefix. This doesn't seem necessary for a type that implements the builder pattern. This commit removes the `set_` prefixes on those four methods.
2023-12-28Use filter instead of filter_map in Parser::expected_one_of_not_foundDaniPopes-18/+20
2023-12-27Auto merge of #117303 - sjwang05:issue-117245, r=estebankbors-0/+20
Suggest `=>` --> `>=` in comparisons Fixes #117245
2023-12-26Suggest `=>` --> `>=` in conditionssjwang05-0/+20
2023-12-24Remove `ParseSess` methods that duplicate `DiagCtxt` methods.Nicholas Nethercote-30/+30
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-26/+12
2023-12-23Give `DiagnosticBuilder` a default type.Nicholas Nethercote-12/+9
`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-12-22Auto merge of #119097 - nnethercote:fix-EmissionGuarantee, r=compiler-errorsbors-12/+10
Fix `EmissionGuarantee` There are some problems with the `DiagCtxt` API related to `EmissionGuarantee`. This PR fixes them. r? `@compiler-errors`
2023-12-20Rollup merge of #118691 - chfogelman:improve-cstr-error, r=fmeaseMatthias Krüger-7/+29
Add check for possible CStr literals in pre-2021 Fixes [#118654](https://github.com/rust-lang/rust/issues/118654) Adds information to errors caused by possible CStr literals in pre-2021. The lexer separates `c"str"` into two tokens if the edition is less than 2021, which later causes an error when parsing. This error now has a more helpful message that directs them to information about editions. However, the user might also have written `c "str"` in a later edition, so to not confuse people who _are_ using a recent edition, I also added a note about whitespace. We could probably figure out exactly which scenario has been encountered by examining spans and editions, but I figured it would be better not to overcomplicate the creation of the error too much. This is my first code PR and I tried to follow existing conventions as much as possible, but I probably missed something, so let me know!
2023-12-19Improve compiler error for c-strings in pre-2021Carter Hunt Fogelman-7/+29
2023-12-18Use `.into_diagnostic()` less.Nicholas Nethercote-12/+10
This commit replaces this pattern: ``` err.into_diagnostic(dcx) ``` with this pattern: ``` dcx.create_err(err) ``` in a lot of places. It's a little shorter, makes the error level explicit, avoids some `IntoDiagnostic` imports, and is a necessary prerequisite for the next commit which will add a `level` arg to `into_diagnostic`. This requires adding `track_caller` on `create_err` to avoid mucking up the output of `tests/ui/track-diagnostics/track4.rs`. It probably should have been there already.
2023-12-18Rename `Parser::span_diagnostic` as `Parser::dcx`.Nicholas Nethercote-10/+10
2023-12-18Rename `ParseSess::span_diagnostic` as `ParseSess::dcx`.Nicholas Nethercote-1/+1
2023-12-18Rename `Handler` as `DiagCtxt`.Nicholas Nethercote-3/+3
2023-12-15Change `msg: impl Into<String>` for bug diagnostics.Nicholas Nethercote-2/+2
To `msg: impl Into<DiagnosticMessage>`, like all the other diagnostics. For consistency.
2023-12-08Auto merge of #118527 - Nadrieril:never_patterns_parse, r=compiler-errorsbors-21/+16
never_patterns: Parse match arms with no body Never patterns are meant to signal unreachable cases, and thus don't take bodies: ```rust let ptr: *const Option<!> = ...; match *ptr { None => { foo(); } Some(!), } ``` This PR makes rustc accept the above, and enforces that an arm has a body xor is a never pattern. This affects parsing of match arms even with the feature off, so this is delicate. (Plus this is my first non-trivial change to the parser). ~~The last commit is optional; it introduces a bit of churn to allow the new suggestions to be machine-applicable. There may be a better solution? I'm not sure.~~ EDIT: I removed that commit r? `@compiler-errors`
2023-12-05Rollup merge of #117922 - estebank:unclosed-generics, r=b-naberMatthias Krüger-9/+34
Tweak unclosed generics errors Remove unnecessary span label for parse errors that already have a suggestion. Provide structured suggestion to close generics in more cases.
2023-12-03Detect attempts to expand a macro to a match arm againNadrieril-21/+16
Because a macro invocation can expand to a never pattern, we can't rule out a `arm!(),` arm at parse time. Instead we detect that case at expansion time, if the macro tries to output a pattern followed by `=>`.
2023-12-03Auto merge of #118542 - chenyukang:yukang-fix-parser-ice-118531, r=cjgillotbors-12/+4
Fix parser ICE from attrs Fixes #118531, Fixes #118530.
2023-12-02Fix parser ICE from attrsyukang-12/+4
2023-12-02Use `Session::diagnostic` in more places.Nicholas Nethercote-10/+9
2023-12-01Tweak unclosed generics errorsEsteban Küber-9/+34
Remove unnecessary span label for parse errors that already have a suggestion. Provide structured suggestion to close generics in more cases.
2023-11-29Change how `for (x in foo) {}` is handledEsteban Küber-37/+6
Use the same approach used for match arm patterns.
2023-11-29More accurate span for unnecessary parens suggestionEsteban Küber-24/+5
2023-11-21Fix `clippy::needless_borrow` in the compilerNilstrieb-4/+4
`x clippy compiler -Aclippy::all -Wclippy::needless_borrow --fix`. Then I had to remove a few unnecessary parens and muts that were exposed now.
2023-11-19Rollup merge of #117988 - estebank:issue-106020, r=cjgillotMichael Goulet-0/+96
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/+96
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-2/+56
Partially address #71039.
2023-11-15Re-format code with new rustfmtMark Rousskov-1/+3
2023-10-30When encountering unclosed delimiters during parsing, check for diff markersEsteban Küber-3/+9
Fix #116252.
2023-10-26Recover ternary expression as errorclubby789-9/+11
2023-10-26Properly restore snapshot when failing to recover parsing ternaryclubby789-4/+2
2023-10-20Move where doc comment meant as comment checkEsteban Küber-1/+21
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-15Auto merge of #116688 - compiler-errors:rustfmt-up, r=WaffleLapkin,Nilstriebbors-42/+50
Format all the let-chains in compiler crates Since rust-lang/rustfmt#5910 has landed, soon we will have support for formatting let-chains (as soon as rustfmt syncs and beta gets bumped). This PR applies the changes [from master rustfmt to rust-lang/rust eagerly](https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/out.20formatting.20of.20prs/near/374997516), so that the next beta bump does not have to deal with a 200+ file diff and can remain concerned with other things like `cfg(bootstrap)` -- #113637 was a pain to land, for example, because of let-else. I will also add this commit to the ignore list after it has landed. The commands that were run -- I'm not great at bash-foo, but this applies rustfmt to every compiler crate, and then reverts the two crates that should probably be formatted out-of-tree. ``` ~/rustfmt $ ls -1d ~/rust/compiler/* | xargs -I@ cargo run --bin rustfmt -- `@/src/lib.rs` --config-path ~/rust --edition=2021 # format all of the compiler crates ~/rust $ git checkout HEAD -- compiler/rustc_codegen_{gcc,cranelift} # revert changes to cg-gcc and cg-clif ``` cc `@rust-lang/rustfmt` r? `@WaffleLapkin` or `@Nilstrieb` who said they may be able to review this purely mechanical PR :> cc `@Mark-Simulacrum` and `@petrochenkov,` who had some thoughts on the order of operations with big formatting changes in https://github.com/rust-lang/rust/pull/95262#issue-1178993801. I think the situation has changed since then, given that let-chains support exists on master rustfmt now, and I'm fairly confident that this formatting PR should land even if *bootstrap* rustfmt doesn't yet format let-chains in order to lessen the burden of the next beta bump.
2023-10-13Format all the let chains in compilerMichael Goulet-42/+50
2023-10-12Detect ruby-style closure in parserEsteban Küber-0/+59
When parsing a closure without a body that is surrounded by a block, suggest moving the opening brace after the closure head. Fix #116608.
2023-09-28Tweak wording of missing angle backets in qualified pathEsteban Küber-4/+3
2023-08-08inlined kinddarklyspaced-2/+1
2023-08-07always return ExprKind::Errdarklyspaced-6/+1
2023-08-04Rollup merge of #113999 - Centri3:macro-arm-expand, r=wesleywiserMatthias Krüger-16/+21
Specify macro is invalid in certain contexts Adds a note when a macro is used where it really shouldn't be. Closes #113766