diff options
| author | bors <bors@rust-lang.org> | 2024-03-12 05:55:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-03-12 05:55:19 +0000 |
| commit | 9b6a6b8f62ffd66545ea9e1858ce9e463cc72801 (patch) | |
| tree | 867759edc0e773810a18d5349733a6d4a11d3ee8 /compiler/rustc_parse/src/parser | |
| parent | 7a5b6eb9dc543cf28e1e27fa138bbf884dc56533 (diff) | |
| parent | 19378ca0969c5a105a03a2d156c10be7b58f6a66 (diff) | |
| download | rust-9b6a6b8f62ffd66545ea9e1858ce9e463cc72801.tar.gz rust-9b6a6b8f62ffd66545ea9e1858ce9e463cc72801.zip | |
Auto merge of #3375 - rust-lang:rustup-2024-03-12, r=oli-obk
Automatic Rustup
Diffstat (limited to 'compiler/rustc_parse/src/parser')
| -rw-r--r-- | compiler/rustc_parse/src/parser/diagnostics.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/path.rs | 86 |
3 files changed, 91 insertions, 9 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index de088b9364b..7038b8bbe47 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -36,8 +36,8 @@ use rustc_ast::{ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ - pluralize, AddToDiagnostic, Applicability, Diag, DiagCtxt, ErrorGuaranteed, FatalError, PErr, - PResult, + pluralize, Applicability, Diag, DiagCtxt, ErrorGuaranteed, FatalError, PErr, PResult, + Subdiagnostic, }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; @@ -298,7 +298,7 @@ impl<'a> Parser<'a> { { recovered_ident = Some((ident, IdentIsRaw::Yes)); - // `Symbol::to_string()` is different from `Symbol::into_diagnostic_arg()`, + // `Symbol::to_string()` is different from `Symbol::into_diag_arg()`, // which uses `Symbol::to_ident_string()` and "helpfully" adds an implicit `r#` let ident_name = ident.name.to_string(); @@ -1271,7 +1271,7 @@ impl<'a> Parser<'a> { Ok(_) => { if self.token == token::Eq { let sugg = SuggAddMissingLetStmt { span: prev_span }; - sugg.add_to_diagnostic(err); + sugg.add_to_diag(err); } } Err(e) => { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 7a34bc7890c..e27a5f93799 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -27,7 +27,7 @@ use rustc_ast::{Arm, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLim use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind}; use rustc_ast_pretty::pprust; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::{AddToDiagnostic, Applicability, Diag, PResult, StashKey}; +use rustc_errors::{Applicability, Diag, PResult, StashKey, Subdiagnostic}; use rustc_lexer::unescape::unescape_char; use rustc_macros::Subdiagnostic; use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded}; @@ -3451,8 +3451,8 @@ impl<'a> Parser<'a> { let in_if_guard = self.restrictions.contains(Restrictions::IN_IF_GUARD); let async_block_err = |e: &mut Diag<'_>, span: Span| { - errors::AsyncBlockIn2015 { span }.add_to_diagnostic(e); - errors::HelpUseLatestEdition::new().add_to_diagnostic(e); + errors::AsyncBlockIn2015 { span }.add_to_diag(e); + errors::HelpUseLatestEdition::new().add_to_diag(e); }; while self.token != token::CloseDelim(close_delim) { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 545db5138a3..2edf2111de7 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -1,6 +1,7 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; use crate::errors::PathSingleColon; +use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma}; use crate::{errors, maybe_whole}; use ast::token::IdentIsRaw; use rustc_ast::ptr::P; @@ -10,7 +11,7 @@ use rustc_ast::{ AssocConstraintKind, BlockCheckMode, GenericArg, GenericArgs, Generics, ParenthesizedArgs, Path, PathSegment, QSelf, }; -use rustc_errors::{Applicability, PResult}; +use rustc_errors::{Applicability, Diag, PResult}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, Span}; use std::mem; @@ -373,7 +374,38 @@ impl<'a> Parser<'a> { .into() } else { // `(T, U) -> R` - let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?; + + let prev_token_before_parsing = self.prev_token.clone(); + let token_before_parsing = self.token.clone(); + let mut snapshot = None; + if self.may_recover() + && prev_token_before_parsing.kind == token::ModSep + && (style == PathStyle::Expr && self.token.can_begin_expr() + || style == PathStyle::Pat && self.token.can_begin_pattern()) + { + snapshot = Some(self.create_snapshot_for_diagnostic()); + } + + let (inputs, _) = match self.parse_paren_comma_seq(|p| p.parse_ty()) { + Ok(output) => output, + Err(mut error) if prev_token_before_parsing.kind == token::ModSep => { + error.span_label( + prev_token_before_parsing.span.to(token_before_parsing.span), + "while parsing this parenthesized list of type arguments starting here", + ); + + if let Some(mut snapshot) = snapshot { + snapshot.recover_fn_call_leading_path_sep( + style, + prev_token_before_parsing, + &mut error, + ) + } + + return Err(error); + } + Err(error) => return Err(error), + }; let inputs_span = lo.to(self.prev_token.span); let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?; @@ -399,6 +431,56 @@ impl<'a> Parser<'a> { } } + /// Recover `$path::(...)` as `$path(...)`. + /// + /// ```ignore (diagnostics) + /// foo::(420, "bar") + /// ^^ remove extra separator to make the function call + /// // or + /// match x { + /// Foo::(420, "bar") => { ... }, + /// ^^ remove extra separator to turn this into tuple struct pattern + /// _ => { ... }, + /// } + /// ``` + fn recover_fn_call_leading_path_sep( + &mut self, + style: PathStyle, + prev_token_before_parsing: Token, + error: &mut Diag<'_>, + ) { + if ((style == PathStyle::Expr && self.parse_paren_comma_seq(|p| p.parse_expr()).is_ok()) + || (style == PathStyle::Pat + && self + .parse_paren_comma_seq(|p| { + p.parse_pat_allow_top_alt( + None, + RecoverComma::No, + RecoverColon::No, + CommaRecoveryMode::LikelyTuple, + ) + }) + .is_ok())) + && !matches!(self.token.kind, token::ModSep | token::RArrow) + { + error.span_suggestion_verbose( + prev_token_before_parsing.span, + format!( + "consider removing the `::` here to {}", + match style { + PathStyle::Expr => "call the expression", + PathStyle::Pat => "turn this into a tuple struct pattern", + _ => { + return; + } + } + ), + "", + Applicability::MaybeIncorrect, + ); + } + } + /// Parses generic args (within a path segment) with recovery for extra leading angle brackets. /// For the purposes of understanding the parsing logic of generic arguments, this function /// can be thought of being the same as just calling `self.parse_angle_args()` if the source |
