diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index e7f17bb6f996d..50351180f8808 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -553,7 +553,7 @@ parse_meta_bad_delim = wrong meta list delimiters parse_meta_bad_delim_suggestion = the delimiters should be `(` and `)` parse_mismatched_closing_delimiter = mismatched closing delimiter: `{$delimiter}` - .label_unmatched = mismatched closing delimiter + .label_unmatched = mismatched closing delimiter{$missing_open_note} .label_opening_candidate = closing delimiter possibly meant for this .label_unclosed = unclosed delimiter diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 44b4e1a3e47a0..6dc0c8a6f6fba 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -945,6 +945,7 @@ pub(crate) struct MismatchedClosingDelimiter { pub delimiter: String, #[label(parse_label_unmatched)] pub unmatched: Span, + pub missing_open_note: String, #[label(parse_label_opening_candidate)] pub opening_candidate: Option, #[label(parse_label_unclosed)] diff --git a/compiler/rustc_parse/src/lexer/diagnostics.rs b/compiler/rustc_parse/src/lexer/diagnostics.rs index e1f19beb53aee..25b7287684955 100644 --- a/compiler/rustc_parse/src/lexer/diagnostics.rs +++ b/compiler/rustc_parse/src/lexer/diagnostics.rs @@ -1,14 +1,24 @@ -use rustc_ast::token::Delimiter; +use rustc_ast::token::{self, Delimiter}; +use rustc_ast_pretty::pprust; use rustc_errors::Diag; +use rustc_session::parse::ParseSess; use rustc_span::Span; use rustc_span::source_map::SourceMap; use super::UnmatchedDelim; +use crate::errors::MismatchedClosingDelimiter; #[derive(Default)] pub(super) struct TokenTreeDiagInfo { + /// record span of `(` for diagnostic + pub open_parens: Vec, + /// record span of `{` for diagnostic + pub open_braces: Vec, + /// record span of `[` for diagnostic + pub open_brackets: Vec, + /// Stack of open delimiters and their spans. Used for error message. - pub open_braces: Vec<(Delimiter, Span)>, + pub open_delimiters: Vec<(Delimiter, Span)>, pub unmatched_delims: Vec, /// Used only for error recovery when arriving to EOF with mismatched braces. @@ -22,6 +32,29 @@ pub(super) struct TokenTreeDiagInfo { pub matching_block_spans: Vec<(Span, Span)>, } +impl TokenTreeDiagInfo { + pub(super) fn push_open_delimiter(&mut self, delim: Delimiter, span: Span) { + self.open_delimiters.push((delim, span)); + match delim { + Delimiter::Parenthesis => self.open_parens.push(span), + Delimiter::Brace => self.open_braces.push(span), + Delimiter::Bracket => self.open_brackets.push(span), + _ => {} + } + } + + pub(super) fn pop_open_delimiter(&mut self) -> Option<(Delimiter, Span)> { + let (delim, span) = self.open_delimiters.pop()?; + match delim { + Delimiter::Parenthesis => self.open_parens.pop(), + Delimiter::Brace => self.open_braces.pop(), + Delimiter::Bracket => self.open_brackets.pop(), + _ => unreachable!(), + }; + Some((delim, span)) + } +} + pub(super) fn same_indentation_level(sm: &SourceMap, open_sp: Span, close_sp: Span) -> bool { match (sm.span_to_margin(open_sp), sm.span_to_margin(close_sp)) { (Some(open_padding), Some(close_padding)) => open_padding == close_padding, @@ -29,27 +62,47 @@ pub(super) fn same_indentation_level(sm: &SourceMap, open_sp: Span, close_sp: Sp } } +pub(crate) fn make_unclosed_delims_error( + unmatched: UnmatchedDelim, + psess: &ParseSess, +) -> Option> { + // `None` here means an `Eof` was found. We already emit those errors elsewhere, we add them to + // `unmatched_delims` only for error recovery in the `Parser`. + let found_delim = unmatched.found_delim?; + let mut spans = vec![unmatched.found_span]; + if let Some(sp) = unmatched.unclosed_span { + spans.push(sp); + }; + + let missing_open_note = report_missing_open_delim(&unmatched) + .map(|s| format!(", may missing open `{s}`")) + .unwrap_or_default(); + + let err = psess.dcx().create_err(MismatchedClosingDelimiter { + spans, + delimiter: pprust::token_kind_to_string(&token::CloseDelim(found_delim)).to_string(), + unmatched: unmatched.found_span, + missing_open_note, + opening_candidate: unmatched.candidate_span, + unclosed: unmatched.unclosed_span, + }); + Some(err) +} + // When we get a `)` or `]` for `{`, we should emit help message here // it's more friendly compared to report `unmatched error` in later phase -fn report_missing_open_delim(err: &mut Diag<'_>, unmatched_delims: &[UnmatchedDelim]) -> bool { - let mut reported_missing_open = false; - for unmatch_brace in unmatched_delims.iter() { - if let Some(delim) = unmatch_brace.found_delim - && matches!(delim, Delimiter::Parenthesis | Delimiter::Bracket) - { - let missed_open = match delim { - Delimiter::Parenthesis => "(", - Delimiter::Bracket => "[", - _ => unreachable!(), - }; - err.span_label( - unmatch_brace.found_span.shrink_to_lo(), - format!("missing open `{missed_open}` for this delimiter"), - ); - reported_missing_open = true; - } +fn report_missing_open_delim(unmatched_delim: &UnmatchedDelim) -> Option { + if let Some(delim) = unmatched_delim.found_delim + && matches!(delim, Delimiter::Parenthesis | Delimiter::Bracket) + { + let missed_open = match delim { + Delimiter::Parenthesis => "(", + Delimiter::Bracket => "[", + _ => unreachable!(), + }; + return Some(missed_open.to_owned()); } - reported_missing_open + None } pub(super) fn report_suspicious_mismatch_block( @@ -58,10 +111,6 @@ pub(super) fn report_suspicious_mismatch_block( sm: &SourceMap, delim: Delimiter, ) { - if report_missing_open_delim(err, &diag_info.unmatched_delims) { - return; - } - let mut matched_spans: Vec<(Span, bool)> = diag_info .matching_block_spans .iter() @@ -108,7 +157,7 @@ pub(super) fn report_suspicious_mismatch_block( } else { // If there is no suspicious span, give the last properly closed block may help if let Some(parent) = diag_info.matching_block_spans.last() - && diag_info.open_braces.last().is_none() + && diag_info.open_delimiters.last().is_none() && diag_info.empty_block_spans.iter().all(|&sp| sp != parent.0.to(parent.1)) { err.span_label(parent.0, "this opening brace..."); diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index 4935fc03256f4..c36e372dcfc17 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -1,5 +1,6 @@ use std::ops::Range; +use diagnostics::make_unclosed_delims_error; use rustc_ast::ast::{self, AttrStyle}; use rustc_ast::token::{self, CommentKind, Delimiter, IdentIsRaw, Token, TokenKind}; use rustc_ast::tokenstream::TokenStream; @@ -17,9 +18,9 @@ use rustc_session::parse::ParseSess; use rustc_span::{BytePos, Pos, Span, Symbol}; use tracing::debug; +use crate::errors; use crate::lexer::diagnostics::TokenTreeDiagInfo; use crate::lexer::unicode_chars::UNICODE_ARRAY; -use crate::{errors, make_unclosed_delims_error}; mod diagnostics; mod tokentrees; diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index b3f83a320241e..0e15cea323b83 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -2,6 +2,7 @@ use rustc_ast::token::{self, Delimiter, Token}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast_pretty::pprust::token_to_string; use rustc_errors::Diag; +use rustc_span::Span; use super::diagnostics::{report_suspicious_mismatch_block, same_indentation_level}; use super::{Lexer, UnmatchedDelim}; @@ -23,7 +24,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { // Invisible delimiters cannot occur here because `TokenTreesReader` parses // code directly from strings, with no macro expansion involved. debug_assert!(!matches!(delim, Delimiter::Invisible(_))); - buf.push(match self.lex_token_tree_open_delim(delim) { + buf.push(match self.lex_token_tree_open_delim(delim, self.token.span) { Ok(val) => val, Err(errs) => return Err(errs), }) @@ -35,6 +36,15 @@ impl<'psess, 'src> Lexer<'psess, 'src> { return if is_delimited { Ok((open_spacing, TokenStream::new(buf))) } else { + let matches_previous_open_delim = match delim { + Delimiter::Parenthesis => self.diag_info.open_parens.last().is_some(), + Delimiter::Brace => self.diag_info.open_braces.last().is_some(), + Delimiter::Bracket => self.diag_info.open_brackets.last().is_some(), + _ => unreachable!(), + }; + if matches_previous_open_delim { + return Err(vec![]); + } Err(vec![self.close_delim_err(delim)]) }; } @@ -59,8 +69,8 @@ impl<'psess, 'src> Lexer<'psess, 'src> { let mut err = self.dcx().struct_span_err(self.token.span, msg); let unclosed_delimiter_show_limit = 5; - let len = usize::min(unclosed_delimiter_show_limit, self.diag_info.open_braces.len()); - for &(_, span) in &self.diag_info.open_braces[..len] { + let len = usize::min(unclosed_delimiter_show_limit, self.diag_info.open_delimiters.len()); + for &(_, span) in &self.diag_info.open_delimiters[..len] { err.span_label(span, "unclosed delimiter"); self.diag_info.unmatched_delims.push(UnmatchedDelim { found_delim: None, @@ -70,19 +80,19 @@ impl<'psess, 'src> Lexer<'psess, 'src> { }); } - if let Some((_, span)) = self.diag_info.open_braces.get(unclosed_delimiter_show_limit) - && self.diag_info.open_braces.len() >= unclosed_delimiter_show_limit + 2 + if let Some((_, span)) = self.diag_info.open_delimiters.get(unclosed_delimiter_show_limit) + && self.diag_info.open_delimiters.len() >= unclosed_delimiter_show_limit + 2 { err.span_label( *span, format!( "another {} unclosed delimiters begin from here", - self.diag_info.open_braces.len() - unclosed_delimiter_show_limit + self.diag_info.open_delimiters.len() - unclosed_delimiter_show_limit ), ); } - if let Some((delim, _)) = self.diag_info.open_braces.last() { + if let Some((delim, _)) = self.diag_info.open_delimiters.last() { report_suspicious_mismatch_block( &mut err, &self.diag_info, @@ -96,11 +106,12 @@ impl<'psess, 'src> Lexer<'psess, 'src> { fn lex_token_tree_open_delim( &mut self, open_delim: Delimiter, + open_delim_span: Span, ) -> Result>> { // The span for beginning of the delimited section. let pre_span = self.token.span; - self.diag_info.open_braces.push((open_delim, self.token.span)); + self.diag_info.push_open_delimiter(open_delim, open_delim_span); // Lex the token trees within the delimiters. // We stop at any delimiter so we can try to recover if the user @@ -114,11 +125,12 @@ impl<'psess, 'src> Lexer<'psess, 'src> { let close_spacing = match self.token.kind { // Correct delimiter. token::CloseDelim(close_delim) if close_delim == open_delim => { - let (open_brace, open_brace_span) = self.diag_info.open_braces.pop().unwrap(); - let close_brace_span = self.token.span; + let (open_delimiter, open_delimiter_span) = + self.diag_info.pop_open_delimiter().unwrap(); + let close_delim_span = self.token.span; if tts.is_empty() && close_delim == Delimiter::Brace { - let empty_block_span = open_brace_span.to(close_brace_span); + let empty_block_span = open_delimiter_span.to(close_delim_span); if !sm.is_multiline(empty_block_span) { // Only track if the block is in the form of `{}`, otherwise it is // likely that it was written on purpose. @@ -127,9 +139,11 @@ impl<'psess, 'src> Lexer<'psess, 'src> { } // only add braces - if let (Delimiter::Brace, Delimiter::Brace) = (open_brace, open_delim) { + if let (Delimiter::Brace, Delimiter::Brace) = (open_delimiter, open_delim) + && open_delimiter_span == open_delim_span + { // Add all the matching spans, we will sort by span later - self.diag_info.matching_block_spans.push((open_brace_span, close_brace_span)); + self.diag_info.matching_block_spans.push((open_delim_span, close_delim_span)); } // Move past the closing delimiter. @@ -146,18 +160,18 @@ impl<'psess, 'src> Lexer<'psess, 'src> { // This is a conservative error: only report the last unclosed // delimiter. The previous unclosed delimiters could actually be // closed! The lexer just hasn't gotten to them yet. - if let Some(&(_, sp)) = self.diag_info.open_braces.last() { + if let Some(&(_, sp)) = self.diag_info.open_delimiters.last() { unclosed_delimiter = Some(sp); }; - for (brace, brace_span) in &self.diag_info.open_braces { - if same_indentation_level(sm, self.token.span, *brace_span) - && brace == &close_delim + for (delim, delim_span) in &self.diag_info.open_delimiters { + if same_indentation_level(sm, self.token.span, *delim_span) + && delim == &close_delim { // high likelihood of these two corresponding - candidate = Some(*brace_span); + candidate = Some(*delim_span); } } - let (_, _) = self.diag_info.open_braces.pop().unwrap(); + let (_, _) = self.diag_info.open_delimiters.pop().unwrap(); self.diag_info.unmatched_delims.push(UnmatchedDelim { found_delim: Some(close_delim), found_span: self.token.span, @@ -165,7 +179,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { candidate_span: candidate, }); } else { - self.diag_info.open_braces.pop(); + self.diag_info.open_delimiters.pop(); } // If the incorrect delimiter matches an earlier opening @@ -175,7 +189,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { // fn foo() { // bar(baz( // } // Incorrect delimiter but matches the earlier `{` - if !self.diag_info.open_braces.iter().any(|&(b, _)| b == close_delim) { + if !self.diag_info.open_delimiters.iter().any(|&(d, _)| d == close_delim) { self.bump_minimal() } else { // The choice of value here doesn't matter. diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 2edc8c83017d8..896e348a12dc1 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -32,7 +32,7 @@ pub const MACRO_ARGUMENTS: Option<&str> = Some("macro arguments"); #[macro_use] pub mod parser; -use parser::{Parser, make_unclosed_delims_error}; +use parser::Parser; pub mod lexer; pub mod validate_attr; diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 2221a261b4c59..27c47a8ed6d27 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -44,11 +44,8 @@ use token_type::TokenTypeSet; pub use token_type::{ExpKeywordPair, ExpTokenPair, TokenType}; use tracing::debug; -use crate::errors::{ - self, IncorrectVisibilityRestriction, MismatchedClosingDelimiter, NonStringAbiLiteral, -}; +use crate::errors::{self, IncorrectVisibilityRestriction, NonStringAbiLiteral}; use crate::exp; -use crate::lexer::UnmatchedDelim; #[cfg(test)] mod tests; @@ -1763,27 +1760,6 @@ impl<'a> Parser<'a> { } } -pub(crate) fn make_unclosed_delims_error( - unmatched: UnmatchedDelim, - psess: &ParseSess, -) -> Option> { - // `None` here means an `Eof` was found. We already emit those errors elsewhere, we add them to - // `unmatched_delims` only for error recovery in the `Parser`. - let found_delim = unmatched.found_delim?; - let mut spans = vec![unmatched.found_span]; - if let Some(sp) = unmatched.unclosed_span { - spans.push(sp); - }; - let err = psess.dcx().create_err(MismatchedClosingDelimiter { - spans, - delimiter: pprust::token_kind_to_string(&token::CloseDelim(found_delim)).to_string(), - unmatched: unmatched.found_span, - opening_candidate: unmatched.candidate_span, - unclosed: unmatched.unclosed_span, - }); - Some(err) -} - /// A helper struct used when building an `AttrTokenStream` from /// a `LazyAttrTokenStream`. Both delimiter and non-delimited tokens /// are stored as `FlatToken::Token`. A vector of `FlatToken`s diff --git a/tests/ui/attributes/z-crate-attr/unbalanced-paren.stderr b/tests/ui/attributes/z-crate-attr/unbalanced-paren.stderr index f6545d1db8bc9..70214af9c5ca0 100644 --- a/tests/ui/attributes/z-crate-attr/unbalanced-paren.stderr +++ b/tests/ui/attributes/z-crate-attr/unbalanced-paren.stderr @@ -2,7 +2,7 @@ error: mismatched closing delimiter: `]` --> :1:4 | LL | #![(] - | -^^ mismatched closing delimiter + | -^^ mismatched closing delimiter, may missing open `[` | || | |unclosed delimiter | closing delimiter possibly meant for this diff --git a/tests/ui/macros/issue-102878.stderr b/tests/ui/macros/issue-102878.stderr index 1971a6bd12e42..30943dcd3cce5 100644 --- a/tests/ui/macros/issue-102878.stderr +++ b/tests/ui/macros/issue-102878.stderr @@ -2,7 +2,7 @@ error: mismatched closing delimiter: `)` --> $DIR/issue-102878.rs:1:35 | LL | macro_rules!test{($l:expr,$_:r)=>({const:y y)} - | -^ ^ mismatched closing delimiter + | -^ ^ mismatched closing delimiter, may missing open `(` | || | |unclosed delimiter | closing delimiter possibly meant for this diff --git a/tests/ui/parser/deli-ident-issue-2.rs b/tests/ui/parser/deli-ident-issue-2.rs index 5394760df7026..661161936811f 100644 --- a/tests/ui/parser/deli-ident-issue-2.rs +++ b/tests/ui/parser/deli-ident-issue-2.rs @@ -2,6 +2,6 @@ fn main() { if 1 < 2 { let _a = vec!]; //~ ERROR mismatched closing delimiter } -} //~ ERROR unexpected closing delimiter +} fn main() {} diff --git a/tests/ui/parser/deli-ident-issue-2.stderr b/tests/ui/parser/deli-ident-issue-2.stderr index e0188cdfb4af8..63bfcc603e750 100644 --- a/tests/ui/parser/deli-ident-issue-2.stderr +++ b/tests/ui/parser/deli-ident-issue-2.stderr @@ -4,16 +4,7 @@ error: mismatched closing delimiter: `]` LL | if 1 < 2 { | ^ unclosed delimiter LL | let _a = vec!]; - | ^ mismatched closing delimiter + | ^ mismatched closing delimiter, may missing open `[` -error: unexpected closing delimiter: `}` - --> $DIR/deli-ident-issue-2.rs:5:1 - | -LL | let _a = vec!]; - | - missing open `[` for this delimiter -LL | } -LL | } - | ^ unexpected closing delimiter - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/parser/do-not-suggest-semicolon-before-array.stderr b/tests/ui/parser/do-not-suggest-semicolon-before-array.stderr index 0227439ce066d..d5d0e253d00f5 100644 --- a/tests/ui/parser/do-not-suggest-semicolon-before-array.stderr +++ b/tests/ui/parser/do-not-suggest-semicolon-before-array.stderr @@ -2,7 +2,7 @@ error: mismatched closing delimiter: `)` --> $DIR/do-not-suggest-semicolon-before-array.rs:5:5 | LL | [1, 3) - | ^ ^ mismatched closing delimiter + | ^ ^ mismatched closing delimiter, may missing open `(` | | | unclosed delimiter diff --git a/tests/ui/parser/issues/issue-104367.stderr b/tests/ui/parser/issues/issue-104367.stderr index c067d12e2d96c..2dda449ec2b2f 100644 --- a/tests/ui/parser/issues/issue-104367.stderr +++ b/tests/ui/parser/issues/issue-104367.stderr @@ -2,7 +2,7 @@ error: mismatched closing delimiter: `)` --> $DIR/issue-104367.rs:5:15 | LL | #![w,) - | ^ ^ mismatched closing delimiter + | ^ ^ mismatched closing delimiter, may missing open `(` | | | unclosed delimiter @@ -18,7 +18,6 @@ LL | d: [u32; { LL | #![cfg] { | - unclosed delimiter LL | #![w,) - | - missing open `(` for this delimiter LL | | ^ diff --git a/tests/ui/parser/issues/issue-105209.stderr b/tests/ui/parser/issues/issue-105209.stderr index 72017e4327de4..38174587a17d4 100644 --- a/tests/ui/parser/issues/issue-105209.stderr +++ b/tests/ui/parser/issues/issue-105209.stderr @@ -2,7 +2,7 @@ error: mismatched closing delimiter: `)` --> $DIR/issue-105209.rs:2:11 | LL | #![c={#![c[)x - | ^^ mismatched closing delimiter + | ^^ mismatched closing delimiter, may missing open `(` | | | unclosed delimiter @@ -10,9 +10,8 @@ error: this file contains an unclosed delimiter --> $DIR/issue-105209.rs:3:68 | LL | #![c={#![c[)x - | - - - - missing open `(` for this delimiter - | | | | - | | | unclosed delimiter + | - - - unclosed delimiter + | | | | | unclosed delimiter | unclosed delimiter LL | diff --git a/tests/ui/parser/issues/issue-10636-1.rs b/tests/ui/parser/issues/issue-10636-1.rs index 77c6072d6fc0a..e14484f0aacfc 100644 --- a/tests/ui/parser/issues/issue-10636-1.rs +++ b/tests/ui/parser/issues/issue-10636-1.rs @@ -3,6 +3,6 @@ struct Obj { member: usize ) //~^ ERROR mismatched closing delimiter -//~| NOTE mismatched closing delimiter +//~| NOTE mismatched closing delimiter, may missing open `(` fn main() {} diff --git a/tests/ui/parser/issues/issue-10636-1.stderr b/tests/ui/parser/issues/issue-10636-1.stderr index a7402e0717b70..020111c903512 100644 --- a/tests/ui/parser/issues/issue-10636-1.stderr +++ b/tests/ui/parser/issues/issue-10636-1.stderr @@ -5,7 +5,7 @@ LL | struct Obj { | ^ unclosed delimiter ... LL | ) - | ^ mismatched closing delimiter + | ^ mismatched closing delimiter, may missing open `(` error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-60075.stderr b/tests/ui/parser/issues/issue-60075.stderr index b40412aba5586..8c1467a7e7e96 100644 --- a/tests/ui/parser/issues/issue-60075.stderr +++ b/tests/ui/parser/issues/issue-60075.stderr @@ -5,7 +5,7 @@ LL | fn qux() -> Option { | ^ unclosed delimiter LL | let _ = if true { LL | }); - | ^ mismatched closing delimiter + | ^ mismatched closing delimiter, may missing open `(` error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-62895.stderr b/tests/ui/parser/issues/issue-62895.stderr index 0ad9ac63ebd45..e819c5cb6f1b0 100644 --- a/tests/ui/parser/issues/issue-62895.stderr +++ b/tests/ui/parser/issues/issue-62895.stderr @@ -5,7 +5,7 @@ LL | mod _ { | ^ unclosed delimiter LL | pub g() -> is LL | (), w20); - | ^ mismatched closing delimiter + | ^ mismatched closing delimiter, may missing open `(` error: mismatched closing delimiter: `)` --> $DIR/issue-62895.rs:4:7 @@ -14,7 +14,7 @@ LL | mod _ { | ^ unclosed delimiter ... LL | (), w20); - | ^ mismatched closing delimiter + | ^ mismatched closing delimiter, may missing open `(` error: aborting due to 2 previous errors diff --git a/tests/ui/parser/issues/issue-62973.stderr b/tests/ui/parser/issues/issue-62973.stderr index ea3e2bebee404..6e6b2fdbb5174 100644 --- a/tests/ui/parser/issues/issue-62973.stderr +++ b/tests/ui/parser/issues/issue-62973.stderr @@ -2,7 +2,7 @@ error: mismatched closing delimiter: `)` --> $DIR/issue-62973.rs:8:27 | LL | fn p() { match s { v, E { [) {) } - | ^^ mismatched closing delimiter + | ^^ mismatched closing delimiter, may missing open `(` | | | unclosed delimiter @@ -10,7 +10,7 @@ error: mismatched closing delimiter: `)` --> $DIR/issue-62973.rs:8:30 | LL | fn p() { match s { v, E { [) {) } - | ^^ mismatched closing delimiter + | ^^ mismatched closing delimiter, may missing open `(` | | | unclosed delimiter @@ -18,10 +18,8 @@ error: this file contains an unclosed delimiter --> $DIR/issue-62973.rs:10:2 | LL | fn p() { match s { v, E { [) {) } - | - - - - missing open `(` for this delimiter - | | | | - | | | missing open `(` for this delimiter - | | unclosed delimiter + | - - unclosed delimiter + | | | unclosed delimiter LL | LL | diff --git a/tests/ui/parser/issues/issue-63116.stderr b/tests/ui/parser/issues/issue-63116.stderr index e5bad84d11262..dbb182d89e66b 100644 --- a/tests/ui/parser/issues/issue-63116.stderr +++ b/tests/ui/parser/issues/issue-63116.stderr @@ -2,7 +2,7 @@ error: mismatched closing delimiter: `]` --> $DIR/issue-63116.rs:4:14 | LL | impl W $DIR/issue-63116.rs:4:18 | LL | impl W $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:27 | LL | V = [PhantomData; { [ () ].len() ].len() as isize, - | - ^ ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter, may missing open `[` | | | | | unclosed delimiter | closing delimiter possibly meant for this @@ -11,7 +11,7 @@ error: mismatched closing delimiter: `]` --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:12:24 | LL | V = [Vec::new; { [].len() ].len() as isize, - | - ^ ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter, may missing open `[` | | | | | unclosed delimiter | closing delimiter possibly meant for this @@ -20,7 +20,7 @@ error: mismatched closing delimiter: `]` --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:19:24 | LL | V = [Vec::new; { [0].len() ].len() as isize, - | - ^ ^ mismatched closing delimiter + | - ^ ^ mismatched closing delimiter, may missing open `[` | | | | | unclosed delimiter | closing delimiter possibly meant for this @@ -28,18 +28,14 @@ LL | V = [Vec::new; { [0].len() ].len() as isize, error: this file contains an unclosed delimiter --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:23:65 | -LL | V = [PhantomData; { [ () ].len() ].len() as isize, - | - missing open `[` for this delimiter -... -LL | V = [Vec::new; { [].len() ].len() as isize, - | - missing open `[` for this delimiter -... LL | mod c { | - unclosed delimiter LL | enum Bug { -LL | V = [Vec::new; { [0].len() ].len() as isize, - | - missing open `[` for this delimiter + | - this delimiter might not be properly closed... ... +LL | } + | - ...as it matches this but it has different indentation +LL | LL | fn main() {} | ^ diff --git a/tests/ui/parser/issues/issue-68987-unmatch-issue-2.rs b/tests/ui/parser/issues/issue-68987-unmatch-issue-2.rs index 89aaa68ba4095..8aa2bba75c720 100644 --- a/tests/ui/parser/issues/issue-68987-unmatch-issue-2.rs +++ b/tests/ui/parser/issues/issue-68987-unmatch-issue-2.rs @@ -11,4 +11,4 @@ async fn obstest() -> Result<> { } else { } -} //~ ERROR unexpected closing delimiter +} diff --git a/tests/ui/parser/issues/issue-68987-unmatch-issue-2.stderr b/tests/ui/parser/issues/issue-68987-unmatch-issue-2.stderr index 0ecb748a0a4ce..5200c9b7d59b8 100644 --- a/tests/ui/parser/issues/issue-68987-unmatch-issue-2.stderr +++ b/tests/ui/parser/issues/issue-68987-unmatch-issue-2.stderr @@ -4,16 +4,7 @@ error: mismatched closing delimiter: `)` LL | async fn obstest() -> Result<> { | ^ unclosed delimiter LL | let obs_connect = || -> Result<(), MyError) { - | ^ mismatched closing delimiter + | ^ mismatched closing delimiter, may missing open `(` -error: unexpected closing delimiter: `}` - --> $DIR/issue-68987-unmatch-issue-2.rs:14:1 - | -LL | let obs_connect = || -> Result<(), MyError) { - | - missing open `(` for this delimiter -... -LL | } - | ^ unexpected closing delimiter - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-68987-unmatch-issue-3.rs b/tests/ui/parser/issues/issue-68987-unmatch-issue-3.rs index e98df8d7c3c4e..a15ecb69b7211 100644 --- a/tests/ui/parser/issues/issue-68987-unmatch-issue-3.rs +++ b/tests/ui/parser/issues/issue-68987-unmatch-issue-3.rs @@ -5,4 +5,4 @@ fn f(i: u32, j: u32) { while cnt < j { write!&mut res, " "); //~ ERROR mismatched closing delimiter } -} //~ ERROR unexpected closing delimiter +} diff --git a/tests/ui/parser/issues/issue-68987-unmatch-issue-3.stderr b/tests/ui/parser/issues/issue-68987-unmatch-issue-3.stderr index dfc4407ed6565..e7e2c755fb595 100644 --- a/tests/ui/parser/issues/issue-68987-unmatch-issue-3.stderr +++ b/tests/ui/parser/issues/issue-68987-unmatch-issue-3.stderr @@ -4,16 +4,7 @@ error: mismatched closing delimiter: `)` LL | while cnt < j { | ^ unclosed delimiter LL | write!&mut res, " "); - | ^ mismatched closing delimiter + | ^ mismatched closing delimiter, may missing open `(` -error: unexpected closing delimiter: `}` - --> $DIR/issue-68987-unmatch-issue-3.rs:8:1 - | -LL | write!&mut res, " "); - | - missing open `(` for this delimiter -LL | } -LL | } - | ^ unexpected closing delimiter - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error diff --git a/tests/ui/parser/issues/issue-81827.stderr b/tests/ui/parser/issues/issue-81827.stderr index 986ed6b7e70f9..8568dcbcb289c 100644 --- a/tests/ui/parser/issues/issue-81827.stderr +++ b/tests/ui/parser/issues/issue-81827.stderr @@ -2,7 +2,7 @@ error: mismatched closing delimiter: `]` --> $DIR/issue-81827.rs:7:23 | LL | fn r()->i{0|{#[cfg(r(0{]0 - | - ^^ mismatched closing delimiter + | - ^^ mismatched closing delimiter, may missing open `[` | | | | | unclosed delimiter | closing delimiter possibly meant for this @@ -11,9 +11,8 @@ error: this file contains an unclosed delimiter --> $DIR/issue-81827.rs:7:27 | LL | fn r()->i{0|{#[cfg(r(0{]0 - | - - - ^ - | | | | - | | | missing open `[` for this delimiter + | - - ^ + | | | | | unclosed delimiter | unclosed delimiter diff --git a/tests/ui/parser/issues/unnessary-error-issue-138401.rs b/tests/ui/parser/issues/unnessary-error-issue-138401.rs new file mode 100644 index 0000000000000..d9ac9b187a814 --- /dev/null +++ b/tests/ui/parser/issues/unnessary-error-issue-138401.rs @@ -0,0 +1,4 @@ +pub fn foo(x: i64) -> i64 { + x.abs) //~ ERROR mismatched closing delimiter +} +fn main() {} diff --git a/tests/ui/parser/issues/unnessary-error-issue-138401.stderr b/tests/ui/parser/issues/unnessary-error-issue-138401.stderr new file mode 100644 index 0000000000000..01c673206e80f --- /dev/null +++ b/tests/ui/parser/issues/unnessary-error-issue-138401.stderr @@ -0,0 +1,10 @@ +error: mismatched closing delimiter: `)` + --> $DIR/unnessary-error-issue-138401.rs:1:27 + | +LL | pub fn foo(x: i64) -> i64 { + | ^ unclosed delimiter +LL | x.abs) + | ^ mismatched closing delimiter, may missing open `(` + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/macro-mismatched-delim-brace-paren.stderr b/tests/ui/parser/macro-mismatched-delim-brace-paren.stderr index f9a3072229f65..40b1cb7f64c06 100644 --- a/tests/ui/parser/macro-mismatched-delim-brace-paren.stderr +++ b/tests/ui/parser/macro-mismatched-delim-brace-paren.stderr @@ -5,7 +5,7 @@ LL | foo! { | ^ unclosed delimiter LL | bar, "baz", 1, 2.0 LL | ) - | ^ mismatched closing delimiter + | ^ mismatched closing delimiter, may missing open `(` error: aborting due to 1 previous error diff --git a/tests/ui/parser/parser-recovery-2.stderr b/tests/ui/parser/parser-recovery-2.stderr index d3d6c9b081023..1e64b93a33061 100644 --- a/tests/ui/parser/parser-recovery-2.stderr +++ b/tests/ui/parser/parser-recovery-2.stderr @@ -5,7 +5,7 @@ LL | fn bar() { | ^ unclosed delimiter LL | let x = foo(); LL | ) - | ^ mismatched closing delimiter + | ^ mismatched closing delimiter, may missing open `(` error: aborting due to 1 previous error diff --git a/tests/ui/resolve/token-error-correct-2.stderr b/tests/ui/resolve/token-error-correct-2.stderr index 662b849da9e60..9e61214736c46 100644 --- a/tests/ui/resolve/token-error-correct-2.stderr +++ b/tests/ui/resolve/token-error-correct-2.stderr @@ -4,7 +4,7 @@ error: mismatched closing delimiter: `)` LL | if foo { | ^ unclosed delimiter LL | ) - | ^ mismatched closing delimiter + | ^ mismatched closing delimiter, may missing open `(` error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/issue-94171.stderr b/tests/ui/suggestions/issue-94171.stderr index bcbd46cd8ecd5..d7a709770c6dc 100644 --- a/tests/ui/suggestions/issue-94171.stderr +++ b/tests/ui/suggestions/issue-94171.stderr @@ -14,7 +14,7 @@ error: mismatched closing delimiter: `]` --> $DIR/issue-94171.rs:1:5 | LL | fn L(]{match - | ^^ mismatched closing delimiter + | ^^ mismatched closing delimiter, may missing open `[` | | | unclosed delimiter @@ -22,9 +22,7 @@ error: this file contains an unclosed delimiter --> $DIR/issue-94171.rs:5:52 | LL | fn L(]{match - | -- unclosed delimiter - | | - | missing open `[` for this delimiter + | - unclosed delimiter LL | (; {` | - - unclosed delimiter | | diff --git a/tests/ui/typeck/issue-91334.stderr b/tests/ui/typeck/issue-91334.stderr index 01e34919ce67d..8aa6a6ddbfccd 100644 --- a/tests/ui/typeck/issue-91334.stderr +++ b/tests/ui/typeck/issue-91334.stderr @@ -2,7 +2,7 @@ error: mismatched closing delimiter: `)` --> $DIR/issue-91334.rs:7:19 | LL | fn f(){||yield(((){), - | - ^^ mismatched closing delimiter + | - ^^ mismatched closing delimiter, may missing open `(` | | | | | unclosed delimiter | closing delimiter possibly meant for this @@ -11,9 +11,8 @@ error: this file contains an unclosed delimiter --> $DIR/issue-91334.rs:7:23 | LL | fn f(){||yield(((){), - | - - - ^ - | | | | - | | | missing open `(` for this delimiter + | - - ^ + | | | | | unclosed delimiter | unclosed delimiter diff --git a/tests/ui/typeck/issue-92481.stderr b/tests/ui/typeck/issue-92481.stderr index a1fdd8359a632..5bbe6843cf961 100644 --- a/tests/ui/typeck/issue-92481.stderr +++ b/tests/ui/typeck/issue-92481.stderr @@ -2,7 +2,7 @@ error: mismatched closing delimiter: `)` --> $DIR/issue-92481.rs:5:6 | LL | fn r({) { - | -^^ mismatched closing delimiter + | -^^ mismatched closing delimiter, may missing open `(` | || | |unclosed delimiter | closing delimiter possibly meant for this