From 229be21d0d5297a66e7fe6b56606d0549bfccd5f Mon Sep 17 00:00:00 2001 From: xizheyin Date: Tue, 24 Jun 2025 16:09:42 +0800 Subject: [PATCH 1/2] Add ui test unnessary-error-issue-138401.rs Signed-off-by: xizheyin --- .../issues/unnessary-error-issue-138401.rs | 7 +++++++ .../unnessary-error-issue-138401.stderr | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/ui/parser/issues/unnessary-error-issue-138401.rs create mode 100644 tests/ui/parser/issues/unnessary-error-issue-138401.stderr 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..e5e5f1ee4e9ce --- /dev/null +++ b/tests/ui/parser/issues/unnessary-error-issue-138401.rs @@ -0,0 +1,7 @@ +pub fn foo(x: i64) -> i64 { + x.abs) + //~^ ERROR mismatched closing delimiter +} +//~^ ERROR unexpected 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..b50f77f1247cd --- /dev/null +++ b/tests/ui/parser/issues/unnessary-error-issue-138401.stderr @@ -0,0 +1,19 @@ +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 + +error: unexpected closing delimiter: `}` + --> $DIR/unnessary-error-issue-138401.rs:4:1 + | +LL | x.abs) + | - missing open `(` for this delimiter +LL | +LL | } + | ^ unexpected closing delimiter + +error: aborting due to 2 previous errors + From 181c1bda0ef33c36e59628de6dd5c6ddf95f599f Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 10 Jul 2025 16:27:40 +0800 Subject: [PATCH 2/2] Deduplicate `unmatched_delims` in `rustc_parse` to reduce confusion Signed-off-by: xizheyin --- compiler/rustc_parse/src/lexer/diagnostics.rs | 20 ++++++++++++------- compiler/rustc_parse/src/lexer/tokentrees.rs | 15 ++++++++++++-- tests/ui/parser/deli-ident-issue-2.rs | 2 +- tests/ui/parser/deli-ident-issue-2.stderr | 12 +++-------- tests/ui/parser/issues/issue-104367.stderr | 1 - tests/ui/parser/issues/issue-105209.rs | 2 +- tests/ui/parser/issues/issue-105209.stderr | 9 ++++----- tests/ui/parser/issues/issue-62973.stderr | 6 ++---- tests/ui/parser/issues/issue-63116.stderr | 5 ++--- ...invalid-syntax-in-enum-discriminant.stderr | 12 ++++------- .../issues/issue-68987-unmatch-issue-2.rs | 2 +- .../issues/issue-68987-unmatch-issue-2.stderr | 12 +++-------- .../issues/issue-68987-unmatch-issue-3.rs | 2 +- .../issues/issue-68987-unmatch-issue-3.stderr | 12 +++-------- tests/ui/parser/issues/issue-81827.stderr | 5 ++--- .../issues/unnessary-error-issue-138401.rs | 3 +-- .../unnessary-error-issue-138401.stderr | 17 +++++----------- tests/ui/suggestions/issue-94171.stderr | 4 +--- tests/ui/typeck/issue-91334.stderr | 5 ++--- 19 files changed, 62 insertions(+), 84 deletions(-) diff --git a/compiler/rustc_parse/src/lexer/diagnostics.rs b/compiler/rustc_parse/src/lexer/diagnostics.rs index 0b97d4e6993bb..6de001fc9985a 100644 --- a/compiler/rustc_parse/src/lexer/diagnostics.rs +++ b/compiler/rustc_parse/src/lexer/diagnostics.rs @@ -34,9 +34,12 @@ pub(super) fn same_indentation_level(sm: &SourceMap, open_sp: Span, close_sp: Sp // 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 { +pub(super) fn report_missing_open_delim( + err: &mut Diag<'_>, + unmatched_delims: &mut Vec, +) -> bool { let mut reported_missing_open = false; - for unmatch_brace in unmatched_delims.iter() { + unmatched_delims.retain(|unmatch_brace| { if let Some(delim) = unmatch_brace.found_delim && matches!(delim, Delimiter::Parenthesis | Delimiter::Bracket) { @@ -45,13 +48,20 @@ fn report_missing_open_delim(err: &mut Diag<'_>, unmatched_delims: &[UnmatchedDe Delimiter::Bracket => "[", _ => unreachable!(), }; + + if let Some(unclosed_span) = unmatch_brace.unclosed_span { + err.span_label(unclosed_span, "the nearest open delimiter"); + } err.span_label( unmatch_brace.found_span.shrink_to_lo(), format!("missing open `{missed_open}` for this delimiter"), ); reported_missing_open = true; + false + } else { + true } - } + }); reported_missing_open } @@ -61,10 +71,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() diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index fbea958dcc598..64748199f28d1 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -3,7 +3,9 @@ use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, Toke use rustc_ast_pretty::pprust::token_to_string; use rustc_errors::Diag; -use super::diagnostics::{report_suspicious_mismatch_block, same_indentation_level}; +use super::diagnostics::{ + report_missing_open_delim, report_suspicious_mismatch_block, same_indentation_level, +}; use super::{Lexer, UnmatchedDelim}; impl<'psess, 'src> Lexer<'psess, 'src> { @@ -244,7 +246,16 @@ impl<'psess, 'src> Lexer<'psess, 'src> { let msg = format!("unexpected closing delimiter: `{token_str}`"); let mut err = self.dcx().struct_span_err(self.token.span, msg); - report_suspicious_mismatch_block(&mut err, &self.diag_info, self.psess.source_map(), delim); + // if there is no missing open delim, report suspicious mismatch block + if !report_missing_open_delim(&mut err, &mut self.diag_info.unmatched_delims) { + report_suspicious_mismatch_block( + &mut err, + &self.diag_info, + self.psess.source_map(), + delim, + ); + } + err.span_label(self.token.span, "unexpected closing delimiter"); err } diff --git a/tests/ui/parser/deli-ident-issue-2.rs b/tests/ui/parser/deli-ident-issue-2.rs index 5394760df7026..419933c68ad69 100644 --- a/tests/ui/parser/deli-ident-issue-2.rs +++ b/tests/ui/parser/deli-ident-issue-2.rs @@ -1,6 +1,6 @@ fn main() { if 1 < 2 { - let _a = vec!]; //~ ERROR mismatched closing delimiter + let _a = vec!]; } } //~ ERROR unexpected closing delimiter diff --git a/tests/ui/parser/deli-ident-issue-2.stderr b/tests/ui/parser/deli-ident-issue-2.stderr index e0188cdfb4af8..703cbf196267a 100644 --- a/tests/ui/parser/deli-ident-issue-2.stderr +++ b/tests/ui/parser/deli-ident-issue-2.stderr @@ -1,19 +1,13 @@ -error: mismatched closing delimiter: `]` - --> $DIR/deli-ident-issue-2.rs:2:14 - | -LL | if 1 < 2 { - | ^ unclosed delimiter -LL | let _a = vec!]; - | ^ mismatched closing delimiter - error: unexpected closing delimiter: `}` --> $DIR/deli-ident-issue-2.rs:5:1 | +LL | if 1 < 2 { + | - the nearest open delimiter 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/issues/issue-104367.stderr b/tests/ui/parser/issues/issue-104367.stderr index c067d12e2d96c..f01fa4a1265f5 100644 --- a/tests/ui/parser/issues/issue-104367.stderr +++ b/tests/ui/parser/issues/issue-104367.stderr @@ -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.rs b/tests/ui/parser/issues/issue-105209.rs index f4e331523bf42..12c902e1d809f 100644 --- a/tests/ui/parser/issues/issue-105209.rs +++ b/tests/ui/parser/issues/issue-105209.rs @@ -1,3 +1,3 @@ //@ compile-flags: -Zunpretty=ast-tree #![c={#![c[)x //~ ERROR mismatched closing delimiter - //~ ERROR this file contains an unclosed delimiter + //~ ERROR this file contains an unclosed delimiter diff --git a/tests/ui/parser/issues/issue-105209.stderr b/tests/ui/parser/issues/issue-105209.stderr index 72017e4327de4..75643d180292b 100644 --- a/tests/ui/parser/issues/issue-105209.stderr +++ b/tests/ui/parser/issues/issue-105209.stderr @@ -7,16 +7,15 @@ LL | #![c={#![c[)x | unclosed delimiter error: this file contains an unclosed delimiter - --> $DIR/issue-105209.rs:3:68 + --> $DIR/issue-105209.rs:3:56 | LL | #![c={#![c[)x - | - - - - missing open `(` for this delimiter - | | | | - | | | unclosed delimiter + | - - - unclosed delimiter + | | | | | unclosed delimiter | unclosed delimiter LL | - | ^ + | ^ 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..c7fc5bc29edae 100644 --- a/tests/ui/parser/issues/issue-62973.stderr +++ b/tests/ui/parser/issues/issue-62973.stderr @@ -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..736a0ac2cf61b 100644 --- a/tests/ui/parser/issues/issue-63116.stderr +++ b/tests/ui/parser/issues/issue-63116.stderr @@ -10,9 +10,8 @@ error: this file contains an unclosed delimiter --> $DIR/issue-63116.rs:4:18 | LL | impl W $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..9b4452ed2a1ac 100644 --- a/tests/ui/parser/issues/issue-68987-unmatch-issue-2.rs +++ b/tests/ui/parser/issues/issue-68987-unmatch-issue-2.rs @@ -1,7 +1,7 @@ // FIXME: this case need more work to fix // currently the TokenTree matching ')' with '{', which is not user friendly for diagnostics async fn obstest() -> Result<> { - let obs_connect = || -> Result<(), MyError) { //~ ERROR mismatched closing delimiter + let obs_connect = || -> Result<(), MyError) { async { } } 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..c29a4ff8dbe68 100644 --- a/tests/ui/parser/issues/issue-68987-unmatch-issue-2.stderr +++ b/tests/ui/parser/issues/issue-68987-unmatch-issue-2.stderr @@ -1,19 +1,13 @@ -error: mismatched closing delimiter: `)` - --> $DIR/issue-68987-unmatch-issue-2.rs:3:32 - | -LL | async fn obstest() -> Result<> { - | ^ unclosed delimiter -LL | let obs_connect = || -> Result<(), MyError) { - | ^ mismatched closing delimiter - error: unexpected closing delimiter: `}` --> $DIR/issue-68987-unmatch-issue-2.rs:14:1 | +LL | async fn obstest() -> Result<> { + | - the nearest open delimiter 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..e71e2730980e4 100644 --- a/tests/ui/parser/issues/issue-68987-unmatch-issue-3.rs +++ b/tests/ui/parser/issues/issue-68987-unmatch-issue-3.rs @@ -3,6 +3,6 @@ fn f(i: u32, j: u32) { let res = String::new(); let mut cnt = i; while cnt < j { - write!&mut res, " "); //~ ERROR mismatched closing delimiter + write!&mut res, " "); } } //~ 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..6b012af1af311 100644 --- a/tests/ui/parser/issues/issue-68987-unmatch-issue-3.stderr +++ b/tests/ui/parser/issues/issue-68987-unmatch-issue-3.stderr @@ -1,19 +1,13 @@ -error: mismatched closing delimiter: `)` - --> $DIR/issue-68987-unmatch-issue-3.rs:5:19 - | -LL | while cnt < j { - | ^ unclosed delimiter -LL | write!&mut res, " "); - | ^ mismatched closing delimiter - error: unexpected closing delimiter: `}` --> $DIR/issue-68987-unmatch-issue-3.rs:8:1 | +LL | while cnt < j { + | - the nearest open delimiter 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..9737c8c90ae7c 100644 --- a/tests/ui/parser/issues/issue-81827.stderr +++ b/tests/ui/parser/issues/issue-81827.stderr @@ -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 index e5e5f1ee4e9ce..208c516365a82 100644 --- a/tests/ui/parser/issues/unnessary-error-issue-138401.rs +++ b/tests/ui/parser/issues/unnessary-error-issue-138401.rs @@ -1,6 +1,5 @@ pub fn foo(x: i64) -> i64 { - x.abs) - //~^ ERROR mismatched closing delimiter + x.abs) } //~^ ERROR unexpected closing delimiter: `}` diff --git a/tests/ui/parser/issues/unnessary-error-issue-138401.stderr b/tests/ui/parser/issues/unnessary-error-issue-138401.stderr index b50f77f1247cd..54c73b50a42ae 100644 --- a/tests/ui/parser/issues/unnessary-error-issue-138401.stderr +++ b/tests/ui/parser/issues/unnessary-error-issue-138401.stderr @@ -1,19 +1,12 @@ -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 - error: unexpected closing delimiter: `}` - --> $DIR/unnessary-error-issue-138401.rs:4:1 + --> $DIR/unnessary-error-issue-138401.rs:3:1 | -LL | x.abs) +LL | pub fn foo(x: i64) -> i64 { + | - the nearest open delimiter +LL | x.abs) | - 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/suggestions/issue-94171.stderr b/tests/ui/suggestions/issue-94171.stderr index bcbd46cd8ecd5..52306a2465f1a 100644 --- a/tests/ui/suggestions/issue-94171.stderr +++ b/tests/ui/suggestions/issue-94171.stderr @@ -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..a348e1ebf7e5a 100644 --- a/tests/ui/typeck/issue-91334.stderr +++ b/tests/ui/typeck/issue-91334.stderr @@ -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