X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_parse%2Fsrc%2Fparser%2Fdiagnostics.rs;h=eda7046c748e5f52121854349a3fa6f903e502d2;hb=f3644ca64de6357a07a3901dd2dacbda247beec6;hp=d9fa3e31db97226cdb4bebcf81cb0d24042c3387;hpb=b102673698a02f280594807a0e3b0448a0a01cdf;p=rust.git diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index d9fa3e31db9..eda7046c748 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -12,9 +12,10 @@ IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, ParenthesesInForHead, ParenthesesInForHeadSugg, PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath, - StructLiteralBodyWithoutPathSugg, SuggEscapeToUseAsIdentifier, SuggRemoveComma, - UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration, - UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, + StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens, StructLiteralNeedingParensSugg, + SuggEscapeToUseAsIdentifier, SuggRemoveComma, UnexpectedConstInGenericParam, + UnexpectedConstParamDeclaration, UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, + UseEqInstead, }; use crate::lexer::UnmatchedBrace; @@ -623,12 +624,15 @@ pub fn maybe_suggest_struct_literal( &mut self, lo: Span, s: BlockCheckMode, + maybe_struct_name: token::Token, + can_be_struct_literal: bool, ) -> Option>> { if self.token.is_ident() && self.look_ahead(1, |t| t == &token::Colon) { // We might be having a struct literal where people forgot to include the path: // fn foo() -> Foo { // field: value, // } + info!(?maybe_struct_name, ?self.token); let mut snapshot = self.create_snapshot_for_diagnostic(); let path = Path { segments: ThinVec::new(), @@ -648,13 +652,6 @@ pub fn maybe_suggest_struct_literal( // field: value, // } } err.delay_as_bug(); - self.sess.emit_err(StructLiteralBodyWithoutPath { - span: expr.span, - sugg: StructLiteralBodyWithoutPathSugg { - before: expr.span.shrink_to_lo(), - after: expr.span.shrink_to_hi(), - }, - }); self.restore_snapshot(snapshot); let mut tail = self.mk_block( vec![self.mk_stmt_err(expr.span)], @@ -662,7 +659,25 @@ pub fn maybe_suggest_struct_literal( lo.to(self.prev_token.span), ); tail.could_be_bare_literal = true; - Ok(tail) + if maybe_struct_name.is_ident() && can_be_struct_literal { + // Account for `if Example { a: one(), }.is_pos() {}`. + Err(self.sess.create_err(StructLiteralNeedingParens { + span: maybe_struct_name.span.to(expr.span), + sugg: StructLiteralNeedingParensSugg { + before: maybe_struct_name.span.shrink_to_lo(), + after: expr.span.shrink_to_hi(), + }, + })) + } else { + self.sess.emit_err(StructLiteralBodyWithoutPath { + span: expr.span, + sugg: StructLiteralBodyWithoutPathSugg { + before: expr.span.shrink_to_lo(), + after: expr.span.shrink_to_hi(), + }, + }); + Ok(tail) + } } (Err(err), Ok(tail)) => { // We have a block tail that contains a somehow valid type ascription expr. @@ -2357,7 +2372,7 @@ pub fn dummy_const_arg_needs_braces( /// Some special error handling for the "top-level" patterns in a match arm, /// `for` loop, `let`, &c. (in contrast to subpatterns within such). - pub(crate) fn maybe_recover_colon_colon_in_pat_typo( + pub(crate) fn maybe_recover_colon_colon_in_pat_typo_or_anon_enum( &mut self, mut first_pat: P, expected: Expected, @@ -2368,26 +2383,41 @@ pub(crate) fn maybe_recover_colon_colon_in_pat_typo( if !matches!(first_pat.kind, PatKind::Ident(_, _, None) | PatKind::Path(..)) || !self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident()) { + let mut snapshot_type = self.create_snapshot_for_diagnostic(); + snapshot_type.bump(); // `:` + match snapshot_type.parse_ty() { + Err(inner_err) => { + inner_err.cancel(); + } + Ok(ty) => { + let Err(mut err) = self.expected_one_of_not_found(&[], &[]) else { + return first_pat; + }; + err.span_label(ty.span, "specifying the type of a pattern isn't supported"); + self.restore_snapshot(snapshot_type); + let span = first_pat.span.to(ty.span); + first_pat = self.mk_pat(span, PatKind::Wild); + err.emit(); + } + } return first_pat; } // The pattern looks like it might be a path with a `::` -> `:` typo: // `match foo { bar:baz => {} }` - let span = self.token.span; + let colon_span = self.token.span; // We only emit "unexpected `:`" error here if we can successfully parse the // whole pattern correctly in that case. - let snapshot = self.create_snapshot_for_diagnostic(); + let mut snapshot_pat = self.create_snapshot_for_diagnostic(); + let mut snapshot_type = self.create_snapshot_for_diagnostic(); // Create error for "unexpected `:`". match self.expected_one_of_not_found(&[], &[]) { Err(mut err) => { - self.bump(); // Skip the `:`. - match self.parse_pat_no_top_alt(expected) { + snapshot_pat.bump(); // Skip the `:`. + snapshot_type.bump(); // Skip the `:`. + match snapshot_pat.parse_pat_no_top_alt(expected) { Err(inner_err) => { - // Carry on as if we had not done anything, callers will emit a - // reasonable error. inner_err.cancel(); - err.cancel(); - self.restore_snapshot(snapshot); } Ok(mut pat) => { // We've parsed the rest of the pattern. @@ -2451,8 +2481,8 @@ pub(crate) fn maybe_recover_colon_colon_in_pat_typo( _ => {} } if show_sugg { - err.span_suggestion( - span, + err.span_suggestion_verbose( + colon_span.until(self.look_ahead(1, |t| t.span)), "maybe write a path separator here", "::", Applicability::MaybeIncorrect, @@ -2460,13 +2490,24 @@ pub(crate) fn maybe_recover_colon_colon_in_pat_typo( } else { first_pat = self.mk_pat(new_span, PatKind::Wild); } - err.emit(); + self.restore_snapshot(snapshot_pat); } } + match snapshot_type.parse_ty() { + Err(inner_err) => { + inner_err.cancel(); + } + Ok(ty) => { + err.span_label(ty.span, "specifying the type of a pattern isn't supported"); + self.restore_snapshot(snapshot_type); + let new_span = first_pat.span.to(ty.span); + first_pat = self.mk_pat(new_span, PatKind::Wild); + } + } + err.emit(); } _ => { // Carry on as if we had not done anything. This should be unreachable. - self.restore_snapshot(snapshot); } }; first_pat