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 3 commits into
base: master
Choose a base branch
from

Conversation

xizheyin
Copy link
Contributor

@xizheyin xizheyin commented Mar 16, 2025

Fixes #138401

@rustbot
Copy link
Collaborator

rustbot commented Mar 16, 2025

r? @compiler-errors

rustbot has assigned @compiler-errors.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 16, 2025
@compiler-errors
Copy link
Member

r? compiler

@rustbot rustbot assigned estebank and unassigned compiler-errors Mar 21, 2025
@chenyukang
Copy link
Member

I changed this part last year, will review this PR later.

r? @chenyukang

@rustbot rustbot assigned chenyukang and unassigned estebank Apr 7, 2025
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 11, 2025
@chenyukang
Copy link
Member

I think this solution introduces some kind of regression on other scenarios(such as the cases I commented).

Maybe we should consider this as a special corner case and provide a special diagnostic for it, it is the pattern that one delimiter is missing the openning delimiter(it's in the inner part), except for this everything is ok, so we should suggest something like "missing openning delimiter ....".

such as:

{ ... {. ) ... }...} missing a inner (
{ ... [ ], ] ...} missing a inner [

@chenyukang
Copy link
Member

@rustbot author

@rustbot
Copy link
Collaborator

rustbot commented Apr 11, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@xizheyin
Copy link
Contributor Author

Thanks, I will revise it soon!

@xizheyin xizheyin changed the title [Lexer] Remove spurious unexpected delimiter error by matching remain… Distinguish delim kind to decide whether to emit unexpected closing delimiter Apr 12, 2025
@xizheyin
Copy link
Contributor Author

This seems like quite a lot of changes, I'll comment in the code to make it easier to REVIEW.

In the first commit, I added the test.

In the second commit I did some clean. I changed a variable name, the original name was inaccurate, I used open_delimiters instead of open_braces for identifying blocks, one should compare spans, not just brace'{'.

In the third commit, I make a distinction between the different delimiters before triggering a unexpected closing delimiter error. But I found that missing open delim note is what triggers in unexpected closing delimiter error.
Therefore, to emit missing open delim note, I also moved missing open delim note to
mismatched closing delimiter error, which can be emitted without delaying to
unexpected closing delimiter error.
And I moved function make_unclosed_delims_error
to src/lexer/diagnostics.rs for clean. And some other clean.

@xizheyin xizheyin requested a review from chenyukang April 12, 2025 11:02
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Apr 12, 2025
@xizheyin
Copy link
Contributor Author

I've combined them into one line so it's more aesthetically pleasing.

mismatched closing delimiter, may missing open `(`

Since the mismatched closing delimiter note and the unclosed delimiter note are related, it may be the better to keep it.

@rust-log-analyzer

This comment has been minimized.

@@ -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 `(`
| ||
Copy link
Member

@chenyukang chenyukang Apr 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is worse too, we are not sure we should replace the left { to ( or replace the right ) to }.

so, the better way is do not suggest any direction.

I think we should only suggest missing a open(or closing) delimiter in the scenario that if we added a open(or closing) delimiter, there will be no error.

@xizheyin
Copy link
Contributor Author

I don't have a good way to judge whether adding the open delimiter is a better way. As in the previous implementation, there will always be some false positives.

If we have to make a balance, should we make suggestions as comprehensively as possible, or would we rather not make suggestions and minimize false positives?

Maybe I need to refactor this code more.

LL | pub fn foo(x: i64) -> i64 {
| ^ unclosed delimiter
LL | x.abs)
| ^ mismatched closing delimiter, may missing open `(`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's better to suggest like this:

missing open `(` for this delimiter

as the origin issue reported wrote in #138401

@chenyukang
Copy link
Member

I have a look at the current code, current output is:

error: mismatched closing delimiter: `)`
 --> ...\test.rs:1:27
  |
1 | pub fn foo(x: i64) -> i64 {
  |                           ^ unclosed delimiter
2 |     x.abs)
  |          ^ mismatched closing delimiter

error: unexpected closing delimiter: `}`
 --> ...\test.rs:3:1
  |
2 |     x.abs)
  |          - missing open `(` for this delimiter
3 | }
  | ^ unexpected closing delimiter

error: aborting due to 2 previous errors

The first diagnostic message is reported at here(you moved it into lexer, it is ok):
https://github.com/chenyukang/rust/blob/c8f94230282a8e8c1148f3e657f0199aad909228/compiler/rustc_parse/src/parser/mod.rs#L1766-L1785

The second diagnostic is reported at here:
https://github.com/chenyukang/rust/blob/c8f94230282a8e8c1148f3e657f0199aad909228/compiler/rustc_parse/src/lexer/diagnostics.rs#L61

To resolve the issue in #138401, can we just remove the first diagnostic if we could report the second one? or at least reorder these two diagnostics, which could also reduce the confusion.

@xizheyin
Copy link
Contributor Author

xizheyin commented Apr 22, 2025

This part of the code conflicted with master, so I submitted the PR #140147 first to do some cleanup, otherwise the code for this PR would have been rather messy. @chenyukang

@wesleywiser
Copy link
Member

@xizheyin now that #140147 has landed, does this PR need to be rebased?

@xizheyin
Copy link
Contributor Author

Yes, I haven't had time to deal with this pr yet. Thanks for reminding me.😁

@chenyukang
Copy link
Member

Yes, I haven't had time to deal with this pr yet. Thanks for reminding me.😁

They review some old PRs every week in the weekly meeting. If you don't plan to move forward with this PR for the time being, you can close it first and reopen it later.

This can prevent this PR from appearing in the review list.

@xizheyin
Copy link
Contributor Author

xizheyin commented Jun 20, 2025

yeah I will take it later. Let me remove it out of the review list first
@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 20, 2025
xizheyin added 2 commits June 24, 2025 16:09
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
…eport to reduce confusion

Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
Copy link
Contributor Author

@xizheyin xizheyin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rustbot ready

let mut reported_missing_open = false;
for unmatch_brace in unmatched_delims.iter() {
unmatched_delims.retain(|unmatch_brace| {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When missing open xxx for this delimiter is reported in the unexpected closing delimiter: xxx error, I remove the corresponding unmatched_delims so that make_unclosed_delims_error doesn't get double report.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all, thank you for all your changes and your patience to improve this output!

Do we have any test left where the lexer diagnostic is still emitted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 24, 2025
Comment on lines -4 to -7
LL | async fn obstest() -> Result<> {
| ^ unclosed delimiter
LL | let obs_connect = || -> Result<(), MyError) {
| ^ mismatched closing delimiter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might make sense to also collect the unclosed opening delimiter to be included in the later error:

error: unexpected closing delimiter: `}`
  --> $DIR/issue-68987-unmatch-issue-2.rs:14:1
   |
LL | async fn obstest() -> Result<> {
   |                                ^ the mismatched closing `)` matches this `{`
LL |     let obs_connect = || -> Result<(), MyError) {
   |                                               - missing open `(` for this delimiter
...
LL | }
   | ^ unexpected closing delimiter

…ng delimiter`

Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
@xizheyin
Copy link
Contributor Author

I marked potential matched unclosed delimiter when emit unexpected closing delimiter in the new commit.
But I am not sure it's appropriate, I think it has the potential to introduce noise into complex samples with lots of mixed delimiters.

@estebank
Copy link
Contributor

@xizheyin I see what you mean. I think some of the changes are a net positive, and some are not. We could try to get fancy and look at the number of unclosed delimiters we have in order to specialize the output. For cases where there's only a handful of mistakes, showing all of them is useful (like when someone deletes a line in the middle of a file). When there are "too many", we can only tell people "try to fix things, this is very broken". I'll try to take a look at this in more depth later with more specific feedback, but if you have the spare time to experiment with this idea, I think it can result on something quite usable.

@xizheyin
Copy link
Contributor Author

That makes sense. Different situations are treated differently. I will investigate further.

if open_delim == close_delim {
err.span_label(
open_delim_span,
format!("the mismatchd closing `{}` may be matched here", token_str),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This message has a typo, and I'd like to tweak the wording here a bit, I just don't have a good idea for what the ideal text would be in context.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something "the mismatched closing {token_str} may be meant for this opening delimiter"?

Comment on lines +2 to 3
#![c={#![c[)x
//~ ERROR this file contains an unclosed delimiter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should make the .stderr output a bit easier to read:

Suggested change
#![c={#![c[)x
//~ ERROR this file contains an unclosed delimiter
//~v ERROR this file contains an unclosed delimiter
#![c={#![c[)x

error: unexpected closing delimiter: `}`
--> $DIR/deli-ident-issue-2.rs:5:1
|
LL | fn main() {
| - the mismatchd closing `}` may be matched here
LL | if 1 < 2 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we should still have a label pointing at this opening {, stating that the closing ] matches it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Better handling of missing closing or opening delimiters, well distinct by type of delimiter
7 participants