Skip to content
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

Incorrect "closure bodies that contain statements must be surrounded by braces" error in unrelatedly invalid code #127223

Open
izik1 opened this issue Jul 1, 2024 · 1 comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@izik1
Copy link

izik1 commented Jul 1, 2024

Code

fn test() {
    let value = || {};

    (value;);
}

Current output

error: closure bodies that contain statements must be surrounded by braces
 --> src/lib.rs:2:17
  |
2 |     let value = || {};
  |                 ^^
3 |
4 |     (value;);
  |            ^
  |
note: statement found outside of a block
 --> src/lib.rs:4:11
  |
2 |     let value = || {};
  |                    -- this expression is a statement because of the trailing semicolon
3 |
4 |     (value;);
  |           ^ this `;` turns the preceding closure into a statement
note: the closure body may be incorrectly delimited
 --> src/lib.rs:2:17
  |
2 |     let value = || {};
  |                 ^^^^^ this is the parsed closure...
3 |
4 |     (value;);
  |            - ...but likely you meant the closure to end here
help: try adding braces
  |
2 ~     let value = || { {};
3 |
4 ~     (value;});
  |

Desired output

error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `;`
 --> src/lib.rs:4:11
  |
4 |     (value;);
  |           ^ expected one of 8 possible tokens

Rationale and extra context

This error is unrelated to the closure, and indeed, applying the suggestion leaves us with:

fn test() {
    let value = || { {};

    (value; });
}

Which now has an improperly closed brace. The correct code would (most likely) be (value)

The original code I had made the suggestion even weirder since the closure was an argument to a Higher Order Function (instead of bound to a variable) and the last line was a function call with a ; after its argument (instead of a paren expression), which happened due to a typo 😅. Just in case something following that structure would make for a useful test case as well:

fn test() {
    let value = std::iter::once_with(|| ());

    std::men::drop(value;);
}

Other cases

No response

Rust Version

❯ rustc +nightly --version --verbose
rustc 1.81.0-nightly (6868c831a 2024-06-30)
binary: rustc
commit-hash: 6868c831a1eb45c5150ff623cef5e42a8b8946d0
commit-date: 2024-06-30
host: aarch64-apple-darwin
release: 1.81.0-nightly
LLVM version: 18.1.7

Anything else?

No response

@izik1 izik1 added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 1, 2024
@izik1 izik1 changed the title Incorrect "closure bodies that contain statements must be surrounded by braces" error unrelatedly invalid code Incorrect "closure bodies that contain statements must be surrounded by braces" error in unrelatedly invalid code Jul 1, 2024
@eggyal
Copy link
Contributor

eggyal commented Jul 2, 2024

Some(closure_spans) if self.token.kind == TokenKind::Semi => {
// Finding a semicolon instead of a comma
// after a closure body indicates that the
// closure body may be a block but the user
// forgot to put braces around its
// statements.
self.recover_missing_braces_around_closure_body(
closure_spans,
expect_err,
)?;
continue;
}

I suppose this test should only be applied when at the same depth as the closure definition?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

2 participants