diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-07-13 19:32:35 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-13 19:32:35 +0530 |
| commit | 980579a5e9f5fcad63ef71f536efec15ccd56511 (patch) | |
| tree | 97af1124c9f5ff63987ced8fce1cf941f2a1fa29 /compiler/rustc_parse/src/parser/expr.rs | |
| parent | 1e7d04b23b6e9d177e7d879b05b4ce3f00ee5a0e (diff) | |
| parent | 9fcb9c6648331f372ee58ce4489d3d43a0723c59 (diff) | |
| download | rust-980579a5e9f5fcad63ef71f536efec15ccd56511.tar.gz rust-980579a5e9f5fcad63ef71f536efec15ccd56511.zip | |
Rollup merge of #99030 - rust-lang:notriddle/field-recovery, r=petrochenkov
diagnostics: error messages when struct literals fail to parse If an expression is supplied where a field is expected, the parser can become convinced that it's a shorthand field syntax when it's not. This PR addresses it by explicitly recording the permitted `:` token immediately after the identifier, and also adds a suggestion to insert the name of the field if it looks like a complex expression. Fixes #98917
Diffstat (limited to 'compiler/rustc_parse/src/parser/expr.rs')
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index f9387e29262..0d9c57908c1 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -3028,6 +3028,11 @@ impl<'a> Parser<'a> { } }; + 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)); + match self.expect_one_of(&[token::Comma], &[token::CloseDelim(close_delim)]) { Ok(_) => { if let Some(f) = parsed_field.or(recovery_field) { @@ -3048,6 +3053,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 { |
