diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-10-12 22:13:26 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-12 22:13:26 +0530 |
| commit | a9a5529eac770084cea00d786ad572e130112ddd (patch) | |
| tree | 2d01aa77fd2bb4059fc276497f62b5d8086dd767 | |
| parent | 117a98c5ceec27ef909bf95e62d079529ce24a82 (diff) | |
| parent | f9d3c8352660451cb14df831002eb1ec514e59e6 (diff) | |
| download | rust-a9a5529eac770084cea00d786ad572e130112ddd.tar.gz rust-a9a5529eac770084cea00d786ad572e130112ddd.zip | |
Rollup merge of #102927 - compiler-errors:let, r=davidtwco
Fix `let` keyword removal suggestion in structs
(1.) Fixes a bug where, given this code:
```rust
struct Foo {
let x: i32,
}
```
We were parsing the field name as `let` instead of `x`, which causes issues later on in the type-checking phase.
(2.) Also, suggestions for `let: i32` as a field regressed, displaying this extra `help:` which is removed by this PR
```
help: remove the let, the `let` keyword is not allowed in struct field definitions
|
2 - let: i32,
2 + : i32,
```
(3.) Makes the suggestion text a bit more succinct, since we don't need to re-explain that `let` is not allowed in this position (since it's in a note that follows). This causes the suggestion to render inline as well.
cc `@gimbles,` this addresses a few nits I mentioned in your PR.
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 17 | ||||
| -rw-r--r-- | src/test/ui/parser/bad-let-as-field.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/parser/bad-let-as-field.stderr | 15 | ||||
| -rw-r--r-- | src/test/ui/parser/removed-syntax-field-let-2.rs | 12 | ||||
| -rw-r--r-- | src/test/ui/parser/removed-syntax-field-let-2.stderr | 33 | ||||
| -rw-r--r-- | src/test/ui/parser/removed-syntax-field-let.stderr | 10 |
6 files changed, 81 insertions, 12 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index e82044a89c4..ebcbc75ba32 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1789,20 +1789,25 @@ impl<'a> Parser<'a> { } } else { let mut err = self.expected_ident_found(); - if let Some((ident, _)) = self.token.ident() && ident.as_str() == "let" { - self.bump(); // `let` - let span = self.prev_token.span.until(self.token.span); + if self.eat_keyword_noexpect(kw::Let) + && let removal_span = self.prev_token.span.until(self.token.span) + && let Ok(ident) = self.parse_ident_common(false) + // Cancel this error, we don't need it. + .map_err(|err| err.cancel()) + && self.token.kind == TokenKind::Colon + { err.span_suggestion( - span, - "remove the let, the `let` keyword is not allowed in struct field definitions", + removal_span, + "remove this `let` keyword", String::new(), Applicability::MachineApplicable, ); err.note("the `let` keyword is not allowed in `struct` fields"); err.note("see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information"); err.emit(); - self.bump(); return Ok(ident); + } else { + self.restore_snapshot(snapshot); } err }; diff --git a/src/test/ui/parser/bad-let-as-field.rs b/src/test/ui/parser/bad-let-as-field.rs new file mode 100644 index 00000000000..fec2bc25617 --- /dev/null +++ b/src/test/ui/parser/bad-let-as-field.rs @@ -0,0 +1,6 @@ +struct Foo { + let: i32, + //~^ ERROR expected identifier, found keyword +} + +fn main() {} diff --git a/src/test/ui/parser/bad-let-as-field.stderr b/src/test/ui/parser/bad-let-as-field.stderr new file mode 100644 index 00000000000..57def42b1ee --- /dev/null +++ b/src/test/ui/parser/bad-let-as-field.stderr @@ -0,0 +1,15 @@ +error: expected identifier, found keyword `let` + --> $DIR/bad-let-as-field.rs:2:5 + | +LL | struct Foo { + | --- while parsing this struct +LL | let: i32, + | ^^^ expected identifier, found keyword + | +help: escape `let` to use it as an identifier + | +LL | r#let: i32, + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/parser/removed-syntax-field-let-2.rs b/src/test/ui/parser/removed-syntax-field-let-2.rs new file mode 100644 index 00000000000..7ff91b476ae --- /dev/null +++ b/src/test/ui/parser/removed-syntax-field-let-2.rs @@ -0,0 +1,12 @@ +struct Foo { + let x: i32, + //~^ ERROR expected identifier, found keyword + let y: i32, + //~^ ERROR expected identifier, found keyword +} + +fn main() { + let _ = Foo { + //~^ ERROR missing fields `x` and `y` in initializer of `Foo` + }; +} diff --git a/src/test/ui/parser/removed-syntax-field-let-2.stderr b/src/test/ui/parser/removed-syntax-field-let-2.stderr new file mode 100644 index 00000000000..fda0919b9b6 --- /dev/null +++ b/src/test/ui/parser/removed-syntax-field-let-2.stderr @@ -0,0 +1,33 @@ +error: expected identifier, found keyword `let` + --> $DIR/removed-syntax-field-let-2.rs:2:5 + | +LL | let x: i32, + | ^^^- + | | + | expected identifier, found keyword + | help: remove this `let` keyword + | + = note: the `let` keyword is not allowed in `struct` fields + = note: see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information + +error: expected identifier, found keyword `let` + --> $DIR/removed-syntax-field-let-2.rs:4:5 + | +LL | let y: i32, + | ^^^- + | | + | expected identifier, found keyword + | help: remove this `let` keyword + | + = note: the `let` keyword is not allowed in `struct` fields + = note: see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information + +error[E0063]: missing fields `x` and `y` in initializer of `Foo` + --> $DIR/removed-syntax-field-let-2.rs:9:13 + | +LL | let _ = Foo { + | ^^^ missing `x` and `y` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0063`. diff --git a/src/test/ui/parser/removed-syntax-field-let.stderr b/src/test/ui/parser/removed-syntax-field-let.stderr index bd1b23f7e3b..9bc18dabd6e 100644 --- a/src/test/ui/parser/removed-syntax-field-let.stderr +++ b/src/test/ui/parser/removed-syntax-field-let.stderr @@ -2,15 +2,13 @@ error: expected identifier, found keyword `let` --> $DIR/removed-syntax-field-let.rs:2:5 | LL | let foo: (), - | ^^^ expected identifier, found keyword + | ^^^- + | | + | expected identifier, found keyword + | help: remove this `let` keyword | = note: the `let` keyword is not allowed in `struct` fields = note: see <https://doc.rust-lang.org/book/ch05-01-defining-structs.html> for more information -help: remove the let, the `let` keyword is not allowed in struct field definitions - | -LL - let foo: (), -LL + foo: (), - | error: aborting due to previous error |
