From d496a4f8bb26709e58ce8821de07f7078d2f615d Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 7 Jul 2022 14:59:54 -0700 Subject: [PATCH 1/3] diagnostics: mention the `:` token when struct fields fail to parse --- compiler/rustc_parse/src/parser/expr.rs | 5 +++++ src/test/ui/parser/issues/issue-52496.stderr | 4 ++-- src/test/ui/parser/issues/issue-62973.stderr | 4 ++-- src/test/ui/parser/removed-syntax-with-2.rs | 2 +- src/test/ui/parser/removed-syntax-with-2.stderr | 4 ++-- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 2c43563b10474..36d633785507c 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3012,6 +3012,11 @@ impl<'a> Parser<'a> { } }; + let is_shorthand = parsed_field.as_ref().map_or(false, |f| f.ident.span == f.expr.span); + // A shorthand field can be turned into a full field with `:`. + // We should point this out. + self.check_or_expected(!is_shorthand, TokenType::Token(token::Colon)); + match self.expect_one_of(&[token::Comma], &[token::CloseDelim(close_delim)]) { Ok(_) => { if let Some(f) = parsed_field.or(recovery_field) { diff --git a/src/test/ui/parser/issues/issue-52496.stderr b/src/test/ui/parser/issues/issue-52496.stderr index 9dbf26ef4b68c..cf5c621020fe8 100644 --- a/src/test/ui/parser/issues/issue-52496.stderr +++ b/src/test/ui/parser/issues/issue-52496.stderr @@ -4,11 +4,11 @@ error: float literals must have an integer part LL | let _ = Foo { bar: .5, baz: 42 }; | ^^ help: must have an integer part: `0.5` -error: expected one of `,` or `}`, found `.` +error: expected one of `,`, `:`, or `}`, found `.` --> $DIR/issue-52496.rs:8:22 | LL | let _ = Foo { bar.into(), bat: -1, . }; - | --- ^ expected one of `,` or `}` + | --- ^ expected one of `,`, `:`, or `}` | | | while parsing this struct diff --git a/src/test/ui/parser/issues/issue-62973.stderr b/src/test/ui/parser/issues/issue-62973.stderr index bc3358fc6baa6..d526c9d0bccca 100644 --- a/src/test/ui/parser/issues/issue-62973.stderr +++ b/src/test/ui/parser/issues/issue-62973.stderr @@ -20,11 +20,11 @@ LL | LL | | ^ -error: expected one of `,` or `}`, found `{` +error: expected one of `,`, `:`, or `}`, found `{` --> $DIR/issue-62973.rs:6:8 | LL | fn p() { match s { v, E { [) {) } - | ^ - -^ expected one of `,` or `}` + | ^ - -^ expected one of `,`, `:`, or `}` | | | | | | | help: `}` may belong here | | while parsing this struct diff --git a/src/test/ui/parser/removed-syntax-with-2.rs b/src/test/ui/parser/removed-syntax-with-2.rs index 8a489e71990fb..451057c66a127 100644 --- a/src/test/ui/parser/removed-syntax-with-2.rs +++ b/src/test/ui/parser/removed-syntax-with-2.rs @@ -6,6 +6,6 @@ fn main() { let a = S { foo: (), bar: () }; let b = S { foo: (), with a }; - //~^ ERROR expected one of `,` or `}`, found `a` + //~^ ERROR expected one of `,`, `:`, or `}`, found `a` //~| ERROR missing field `bar` in initializer of `S` } diff --git a/src/test/ui/parser/removed-syntax-with-2.stderr b/src/test/ui/parser/removed-syntax-with-2.stderr index 2c96dceb587ec..c6ae1ce674ff8 100644 --- a/src/test/ui/parser/removed-syntax-with-2.stderr +++ b/src/test/ui/parser/removed-syntax-with-2.stderr @@ -1,8 +1,8 @@ -error: expected one of `,` or `}`, found `a` +error: expected one of `,`, `:`, or `}`, found `a` --> $DIR/removed-syntax-with-2.rs:8:31 | LL | let b = S { foo: (), with a }; - | - ^ expected one of `,` or `}` + | - ^ expected one of `,`, `:`, or `}` | | | while parsing this struct From 6713dde898ef81042a51d940d36150c52cb697b6 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 7 Jul 2022 15:20:08 -0700 Subject: [PATCH 2/3] diagnostics: suggest naming a field after failing to parse --- compiler/rustc_parse/src/parser/expr.rs | 13 +++++++++++++ src/test/ui/parser/issues/issue-52496.stderr | 5 +++-- src/test/ui/parser/issues/issue-62973.stderr | 14 +++++++++++--- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 36d633785507c..f2765e4997ce4 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3037,6 +3037,19 @@ impl<'a> Parser<'a> { ",", Applicability::MachineApplicable, ); + } else if is_shorthand + && (AssocOp::from_token(&self.token).is_some() + || matches!(&self.token.kind, token::OpenDelim(_)) + || self.token.kind == token::Dot) + { + // Looks like they tried to write a shorthand, complex expression. + let ident = parsed_field.expect("is_shorthand implies Some").ident; + e.span_suggestion( + ident.span.shrink_to_lo(), + "try naming a field", + &format!("{ident}: "), + Applicability::HasPlaceholders, + ); } } if !recover { diff --git a/src/test/ui/parser/issues/issue-52496.stderr b/src/test/ui/parser/issues/issue-52496.stderr index cf5c621020fe8..77335c64c2120 100644 --- a/src/test/ui/parser/issues/issue-52496.stderr +++ b/src/test/ui/parser/issues/issue-52496.stderr @@ -8,8 +8,9 @@ error: expected one of `,`, `:`, or `}`, found `.` --> $DIR/issue-52496.rs:8:22 | LL | let _ = Foo { bar.into(), bat: -1, . }; - | --- ^ expected one of `,`, `:`, or `}` - | | + | --- - ^ expected one of `,`, `:`, or `}` + | | | + | | help: try naming a field: `bar:` | while parsing this struct error: expected identifier, found `.` diff --git a/src/test/ui/parser/issues/issue-62973.stderr b/src/test/ui/parser/issues/issue-62973.stderr index d526c9d0bccca..4737bc71860c2 100644 --- a/src/test/ui/parser/issues/issue-62973.stderr +++ b/src/test/ui/parser/issues/issue-62973.stderr @@ -24,11 +24,19 @@ error: expected one of `,`, `:`, or `}`, found `{` --> $DIR/issue-62973.rs:6:8 | LL | fn p() { match s { v, E { [) {) } - | ^ - -^ expected one of `,`, `:`, or `}` - | | | | - | | | help: `}` may belong here + | ^ - ^ expected one of `,`, `:`, or `}` + | | | | | while parsing this struct | unclosed delimiter + | +help: `}` may belong here + | +LL | fn p() { match s { v, E} { [) {) } + | + +help: try naming a field + | +LL | fn p() { match s { v, E: E { [) {) } + | ++ error: struct literals are not allowed here --> $DIR/issue-62973.rs:6:16 From 9fcb9c6648331f372ee58ce4489d3d43a0723c59 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 12 Jul 2022 07:34:49 -0700 Subject: [PATCH 3/3] Update compiler/rustc_parse/src/parser/expr.rs Co-authored-by: Vadim Petrochenkov --- compiler/rustc_parse/src/parser/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index f2765e4997ce4..52fefa2ebe590 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3012,7 +3012,7 @@ impl<'a> Parser<'a> { } }; - let is_shorthand = parsed_field.as_ref().map_or(false, |f| f.ident.span == f.expr.span); + let is_shorthand = parsed_field.as_ref().map_or(false, |f| f.is_shorthand); // A shorthand field can be turned into a full field with `:`. // We should point this out. self.check_or_expected(!is_shorthand, TokenType::Token(token::Colon));