Deduplicate unmatched_delims in rustc_parse to reduce confusion

Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
This commit is contained in:
xizheyin
2025-07-10 16:27:40 +08:00
parent 229be21d0d
commit 181c1bda0e
19 changed files with 62 additions and 84 deletions

View File

@@ -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 // When we get a `)` or `]` for `{`, we should emit help message here
// it's more friendly compared to report `unmatched error` in later phase // 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<UnmatchedDelim>,
) -> bool {
let mut reported_missing_open = false; 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 if let Some(delim) = unmatch_brace.found_delim
&& matches!(delim, Delimiter::Parenthesis | Delimiter::Bracket) && matches!(delim, Delimiter::Parenthesis | Delimiter::Bracket)
{ {
@@ -45,13 +48,20 @@ fn report_missing_open_delim(err: &mut Diag<'_>, unmatched_delims: &[UnmatchedDe
Delimiter::Bracket => "[", Delimiter::Bracket => "[",
_ => unreachable!(), _ => unreachable!(),
}; };
if let Some(unclosed_span) = unmatch_brace.unclosed_span {
err.span_label(unclosed_span, "the nearest open delimiter");
}
err.span_label( err.span_label(
unmatch_brace.found_span.shrink_to_lo(), unmatch_brace.found_span.shrink_to_lo(),
format!("missing open `{missed_open}` for this delimiter"), format!("missing open `{missed_open}` for this delimiter"),
); );
reported_missing_open = true; reported_missing_open = true;
false
} else {
true
} }
} });
reported_missing_open reported_missing_open
} }
@@ -61,10 +71,6 @@ pub(super) fn report_suspicious_mismatch_block(
sm: &SourceMap, sm: &SourceMap,
delim: Delimiter, delim: Delimiter,
) { ) {
if report_missing_open_delim(err, &diag_info.unmatched_delims) {
return;
}
let mut matched_spans: Vec<(Span, bool)> = diag_info let mut matched_spans: Vec<(Span, bool)> = diag_info
.matching_block_spans .matching_block_spans
.iter() .iter()

View File

@@ -3,7 +3,9 @@ use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, Toke
use rustc_ast_pretty::pprust::token_to_string; use rustc_ast_pretty::pprust::token_to_string;
use rustc_errors::Diag; 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}; use super::{Lexer, UnmatchedDelim};
impl<'psess, 'src> Lexer<'psess, 'src> { 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 msg = format!("unexpected closing delimiter: `{token_str}`");
let mut err = self.dcx().struct_span_err(self.token.span, msg); 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.span_label(self.token.span, "unexpected closing delimiter");
err err
} }

View File

@@ -1,6 +1,6 @@
fn main() { fn main() {
if 1 < 2 { if 1 < 2 {
let _a = vec!]; //~ ERROR mismatched closing delimiter let _a = vec!];
} }
} //~ ERROR unexpected closing delimiter } //~ ERROR unexpected closing delimiter

View File

@@ -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: `}` error: unexpected closing delimiter: `}`
--> $DIR/deli-ident-issue-2.rs:5:1 --> $DIR/deli-ident-issue-2.rs:5:1
| |
LL | if 1 < 2 {
| - the nearest open delimiter
LL | let _a = vec!]; LL | let _a = vec!];
| - missing open `[` for this delimiter | - missing open `[` for this delimiter
LL | } LL | }
LL | } LL | }
| ^ unexpected closing delimiter | ^ unexpected closing delimiter
error: aborting due to 2 previous errors error: aborting due to 1 previous error

View File

@@ -18,7 +18,6 @@ LL | d: [u32; {
LL | #![cfg] { LL | #![cfg] {
| - unclosed delimiter | - unclosed delimiter
LL | #![w,) LL | #![w,)
| - missing open `(` for this delimiter
LL | LL |
| ^ | ^

View File

@@ -7,12 +7,11 @@ LL | #![c={#![c[)x
| unclosed delimiter | unclosed delimiter
error: this file contains an 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 LL | #![c={#![c[)x
| - - - - missing open `(` for this delimiter | - - - unclosed delimiter
| | | | | | |
| | | unclosed delimiter
| | unclosed delimiter | | unclosed delimiter
| unclosed delimiter | unclosed delimiter
LL | LL |

View File

@@ -18,10 +18,8 @@ error: this file contains an unclosed delimiter
--> $DIR/issue-62973.rs:10:2 --> $DIR/issue-62973.rs:10:2
| |
LL | fn p() { match s { v, E { [) {) } LL | fn p() { match s { v, E { [) {) }
| - - - - missing open `(` for this delimiter | - - unclosed delimiter
| | | | | |
| | | missing open `(` for this delimiter
| | unclosed delimiter
| unclosed delimiter | unclosed delimiter
LL | LL |
LL | LL |

View File

@@ -10,9 +10,8 @@ error: this file contains an unclosed delimiter
--> $DIR/issue-63116.rs:4:18 --> $DIR/issue-63116.rs:4:18
| |
LL | impl W <s(f;Y(;] LL | impl W <s(f;Y(;]
| - -^ | - ^
| | | | |
| | missing open `[` for this delimiter
| unclosed delimiter | unclosed delimiter
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@@ -28,18 +28,14 @@ LL | V = [Vec::new; { [0].len() ].len() as isize,
error: this file contains an unclosed delimiter error: this file contains an unclosed delimiter
--> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:23:65 --> $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 { LL | mod c {
| - unclosed delimiter | - unclosed delimiter
LL | enum Bug { LL | enum Bug {
LL | V = [Vec::new; { [0].len() ].len() as isize, | - this delimiter might not be properly closed...
| - missing open `[` for this delimiter
... ...
LL | }
| - ...as it matches this but it has different indentation
LL |
LL | fn main() {} LL | fn main() {}
| ^ | ^

View File

@@ -1,7 +1,7 @@
// FIXME: this case need more work to fix // FIXME: this case need more work to fix
// currently the TokenTree matching ')' with '{', which is not user friendly for diagnostics // currently the TokenTree matching ')' with '{', which is not user friendly for diagnostics
async fn obstest() -> Result<> { async fn obstest() -> Result<> {
let obs_connect = || -> Result<(), MyError) { //~ ERROR mismatched closing delimiter let obs_connect = || -> Result<(), MyError) {
async { async {
} }
} }

View File

@@ -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: `}` error: unexpected closing delimiter: `}`
--> $DIR/issue-68987-unmatch-issue-2.rs:14:1 --> $DIR/issue-68987-unmatch-issue-2.rs:14:1
| |
LL | async fn obstest() -> Result<> {
| - the nearest open delimiter
LL | let obs_connect = || -> Result<(), MyError) { LL | let obs_connect = || -> Result<(), MyError) {
| - missing open `(` for this delimiter | - missing open `(` for this delimiter
... ...
LL | } LL | }
| ^ unexpected closing delimiter | ^ unexpected closing delimiter
error: aborting due to 2 previous errors error: aborting due to 1 previous error

View File

@@ -3,6 +3,6 @@ fn f(i: u32, j: u32) {
let res = String::new(); let res = String::new();
let mut cnt = i; let mut cnt = i;
while cnt < j { while cnt < j {
write!&mut res, " "); //~ ERROR mismatched closing delimiter write!&mut res, " ");
} }
} //~ ERROR unexpected closing delimiter } //~ ERROR unexpected closing delimiter

View File

@@ -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: `}` error: unexpected closing delimiter: `}`
--> $DIR/issue-68987-unmatch-issue-3.rs:8:1 --> $DIR/issue-68987-unmatch-issue-3.rs:8:1
| |
LL | while cnt < j {
| - the nearest open delimiter
LL | write!&mut res, " "); LL | write!&mut res, " ");
| - missing open `(` for this delimiter | - missing open `(` for this delimiter
LL | } LL | }
LL | } LL | }
| ^ unexpected closing delimiter | ^ unexpected closing delimiter
error: aborting due to 2 previous errors error: aborting due to 1 previous error

View File

@@ -11,9 +11,8 @@ error: this file contains an unclosed delimiter
--> $DIR/issue-81827.rs:7:27 --> $DIR/issue-81827.rs:7:27
| |
LL | fn r()->i{0|{#[cfg(r(0{]0 LL | fn r()->i{0|{#[cfg(r(0{]0
| - - - ^ | - - ^
| | | | | | |
| | | missing open `[` for this delimiter
| | unclosed delimiter | | unclosed delimiter
| unclosed delimiter | unclosed delimiter

View File

@@ -1,6 +1,5 @@
pub fn foo(x: i64) -> i64 { pub fn foo(x: i64) -> i64 {
x.abs) x.abs)
//~^ ERROR mismatched closing delimiter
} }
//~^ ERROR unexpected closing delimiter: `}` //~^ ERROR unexpected closing delimiter: `}`

View File

@@ -1,19 +1,12 @@
error: mismatched closing delimiter: `)` error: unexpected closing delimiter: `}`
--> $DIR/unnessary-error-issue-138401.rs:1:27 --> $DIR/unnessary-error-issue-138401.rs:3:1
| |
LL | pub fn foo(x: i64) -> i64 { LL | pub fn foo(x: i64) -> i64 {
| ^ unclosed delimiter | - the nearest open delimiter
LL | x.abs)
| ^ mismatched closing delimiter
error: unexpected closing delimiter: `}`
--> $DIR/unnessary-error-issue-138401.rs:4:1
|
LL | x.abs) LL | x.abs)
| - missing open `(` for this delimiter | - missing open `(` for this delimiter
LL |
LL | } LL | }
| ^ unexpected closing delimiter | ^ unexpected closing delimiter
error: aborting due to 2 previous errors error: aborting due to 1 previous error

View File

@@ -22,9 +22,7 @@ error: this file contains an unclosed delimiter
--> $DIR/issue-94171.rs:5:52 --> $DIR/issue-94171.rs:5:52
| |
LL | fn L(]{match LL | fn L(]{match
| -- unclosed delimiter | - unclosed delimiter
| |
| missing open `[` for this delimiter
LL | (; {` LL | (; {`
| - - unclosed delimiter | - - unclosed delimiter
| | | |

View File

@@ -11,9 +11,8 @@ error: this file contains an unclosed delimiter
--> $DIR/issue-91334.rs:7:23 --> $DIR/issue-91334.rs:7:23
| |
LL | fn f(){||yield(((){), LL | fn f(){||yield(((){),
| - - - ^ | - - ^
| | | | | | |
| | | missing open `(` for this delimiter
| | unclosed delimiter | | unclosed delimiter
| unclosed delimiter | unclosed delimiter