Skip to content

Distinguish delim kind to decide whether to emit unexpected closing delimiter #138554

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions compiler/rustc_parse/src/lexer/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -45,26 +48,29 @@ 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, "unclosed delimiter before unmatched 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
}

pub(super) fn report_suspicious_mismatch_block(
err: &mut Diag<'_>,
diag_info: &TokenTreeDiagInfo,
diag_info: &mut TokenTreeDiagInfo,
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()
Expand Down
25 changes: 19 additions & 6 deletions compiler/rustc_parse/src/lexer/tokentrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down Expand Up @@ -77,12 +79,12 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
);
}

if let Some((delim, _)) = self.diag_info.open_delimiters.last() {
if let Some((delim, _)) = self.diag_info.open_delimiters.last().cloned() {
report_suspicious_mismatch_block(
&mut err,
&self.diag_info,
&mut self.diag_info,
self.psess.source_map(),
*delim,
delim,
)
}
err
Expand Down Expand Up @@ -238,14 +240,25 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
this_spacing
}

fn close_delim_err(&mut self, delim: Delimiter) -> Diag<'psess> {
fn close_delim_err(&mut self, close_delim: Delimiter) -> Diag<'psess> {
// An unexpected closing delimiter (i.e., there is no matching opening delimiter).
let token_str = token_to_string(&self.token);
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);
err.span_label(self.token.span, "unexpected closing delimiter");

if report_missing_open_delim(&mut err, &mut self.diag_info.unmatched_delims) {
return err;
}

report_suspicious_mismatch_block(
&mut err,
&mut self.diag_info,
self.psess.source_map(),
close_delim,
);

err
}
}
2 changes: 1 addition & 1 deletion tests/ui/parser/deli-ident-issue-2.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
fn main() {
if 1 < 2 {
let _a = vec!]; //~ ERROR mismatched closing delimiter
let _a = vec!];
}
} //~ ERROR unexpected closing delimiter

Expand Down
12 changes: 3 additions & 9 deletions tests/ui/parser/deli-ident-issue-2.stderr
Original file line number Diff line number Diff line change
@@ -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 {
| - unclosed delimiter before unmatched 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

1 change: 0 additions & 1 deletion tests/ui/parser/issues/issue-104367.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ LL | d: [u32; {
LL | #![cfg] {
| - unclosed delimiter
LL | #![w,)
| - missing open `(` for this delimiter
LL |
| ^

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/parser/issues/issue-105209.rs
Original file line number Diff line number Diff line change
@@ -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
9 changes: 4 additions & 5 deletions tests/ui/parser/issues/issue-105209.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

6 changes: 2 additions & 4 deletions tests/ui/parser/issues/issue-62973.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
5 changes: 2 additions & 3 deletions tests/ui/parser/issues/issue-63116.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
| ^

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/parser/issues/issue-68987-unmatch-issue-2.rs
Original file line number Diff line number Diff line change
@@ -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 {
}
}
Expand Down
12 changes: 3 additions & 9 deletions tests/ui/parser/issues/issue-68987-unmatch-issue-2.stderr
Original file line number Diff line number Diff line change
@@ -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<> {
| - unclosed delimiter before unmatched 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

2 changes: 1 addition & 1 deletion tests/ui/parser/issues/issue-68987-unmatch-issue-3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
12 changes: 3 additions & 9 deletions tests/ui/parser/issues/issue-68987-unmatch-issue-3.stderr
Original file line number Diff line number Diff line change
@@ -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 {
| - unclosed delimiter before unmatched 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

5 changes: 2 additions & 3 deletions tests/ui/parser/issues/issue-81827.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/parser/issues/unnessary-error-issue-138401.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pub fn foo(x: i64) -> i64 {
x.abs)
}
//~^ ERROR unexpected closing delimiter: `}`

fn main() {}
12 changes: 12 additions & 0 deletions tests/ui/parser/issues/unnessary-error-issue-138401.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error: unexpected closing delimiter: `}`
--> $DIR/unnessary-error-issue-138401.rs:3:1
|
LL | pub fn foo(x: i64) -> i64 {
| - unclosed delimiter before unmatched delimiter
LL | x.abs)
| - missing open `(` for this delimiter
LL | }
| ^ unexpected closing delimiter

error: aborting due to 1 previous error

4 changes: 1 addition & 3 deletions tests/ui/suggestions/issue-94171.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
| |
Expand Down
5 changes: 2 additions & 3 deletions tests/ui/typeck/issue-91334.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading