about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-07-18 19:14:42 +0200
committerGitHub <noreply@github.com>2025-07-18 19:14:42 +0200
commit61285e211bf3d323d2c5d649c99207c500cc0cc2 (patch)
tree5cafee0e56a1304cdf17ca969953edfdc522638b
parent82310651b93a594a3fd69015e1562186a080d94c (diff)
parent181c1bda0ef33c36e59628de6dd5c6ddf95f599f (diff)
downloadrust-61285e211bf3d323d2c5d649c99207c500cc0cc2.tar.gz
rust-61285e211bf3d323d2c5d649c99207c500cc0cc2.zip
Rollup merge of #138554 - xizheyin:issue-138401, r=chenyukang
Distinguish delim kind to decide whether to emit unexpected closing delimiter

Fixes #138401
-rw-r--r--compiler/rustc_parse/src/lexer/diagnostics.rs20
-rw-r--r--compiler/rustc_parse/src/lexer/tokentrees.rs15
-rw-r--r--tests/ui/parser/deli-ident-issue-2.rs2
-rw-r--r--tests/ui/parser/deli-ident-issue-2.stderr12
-rw-r--r--tests/ui/parser/issues/issue-104367.stderr1
-rw-r--r--tests/ui/parser/issues/issue-105209.rs2
-rw-r--r--tests/ui/parser/issues/issue-105209.stderr9
-rw-r--r--tests/ui/parser/issues/issue-62973.stderr6
-rw-r--r--tests/ui/parser/issues/issue-63116.stderr5
-rw-r--r--tests/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr12
-rw-r--r--tests/ui/parser/issues/issue-68987-unmatch-issue-2.rs2
-rw-r--r--tests/ui/parser/issues/issue-68987-unmatch-issue-2.stderr12
-rw-r--r--tests/ui/parser/issues/issue-68987-unmatch-issue-3.rs2
-rw-r--r--tests/ui/parser/issues/issue-68987-unmatch-issue-3.stderr12
-rw-r--r--tests/ui/parser/issues/issue-81827.stderr5
-rw-r--r--tests/ui/parser/issues/unnessary-error-issue-138401.rs6
-rw-r--r--tests/ui/parser/issues/unnessary-error-issue-138401.stderr12
-rw-r--r--tests/ui/suggestions/issue-94171.stderr4
-rw-r--r--tests/ui/typeck/issue-91334.stderr5
19 files changed, 74 insertions, 70 deletions
diff --git a/compiler/rustc_parse/src/lexer/diagnostics.rs b/compiler/rustc_parse/src/lexer/diagnostics.rs
index 0b97d4e6993..6de001fc998 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<UnmatchedDelim>,
+) -> 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 fbea958dcc5..64748199f28 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 5394760df70..419933c68ad 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 e0188cdfb4a..703cbf19626 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 c067d12e2d9..f01fa4a1265 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 f4e331523bf..12c902e1d80 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 72017e4327d..75643d18029 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 ea3e2bebee4..c7fc5bc29ed 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 e5bad84d112..736a0ac2cf6 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 <s(f;Y(;]
-   |          -     -^
-   |          |     |
-   |          |     missing open `[` for this delimiter
+   |          -      ^
+   |          |
    |          unclosed delimiter
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/tests/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr
index b82b0f3255b..5301d43e2ae 100644
--- a/tests/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr
+++ b/tests/ui/parser/issues/issue-67377-invalid-syntax-in-enum-discriminant.stderr
@@ -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 89aaa68ba40..9b4452ed2a1 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 0ecb748a0a4..c29a4ff8dbe 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 e98df8d7c3c..e71e2730980 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 dfc4407ed65..6b012af1af3 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 986ed6b7e70..9737c8c90ae 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
new file mode 100644
index 00000000000..208c516365a
--- /dev/null
+++ b/tests/ui/parser/issues/unnessary-error-issue-138401.rs
@@ -0,0 +1,6 @@
+pub fn foo(x: i64) -> i64 {
+    x.abs)
+}
+//~^ 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 00000000000..54c73b50a42
--- /dev/null
+++ b/tests/ui/parser/issues/unnessary-error-issue-138401.stderr
@@ -0,0 +1,12 @@
+error: unexpected closing delimiter: `}`
+  --> $DIR/unnessary-error-issue-138401.rs:3:1
+   |
+LL | pub fn foo(x: i64) -> i64 {
+   |                           - the nearest open delimiter
+LL |     x.abs)
+   |          - missing open `(` for this delimiter
+LL | }
+   | ^ unexpected closing delimiter
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/suggestions/issue-94171.stderr b/tests/ui/suggestions/issue-94171.stderr
index bcbd46cd8ec..52306a2465f 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 01e34919ce6..a348e1ebf7e 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