Skip to content

Bad suggestion on missing block inside of a closure #107959

New issue

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

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

Already on GitHub? # to your account

Closed
GoldsteinE opened this issue Feb 12, 2023 · 1 comment · Fixed by #108388
Closed

Bad suggestion on missing block inside of a closure #107959

GoldsteinE opened this issue Feb 12, 2023 · 1 comment · Fixed by #108388
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The lexing & parsing of Rust source code to an AST T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@GoldsteinE
Copy link
Contributor

GoldsteinE commented Feb 12, 2023

Code

fn main() {
    let _x = std::boxed::Box::new(|x|x+1;);
}

Current output

error: closure bodies that contain statements must be surrounded by braces
 --> src/main.rs:2:37
  |
2 |     let _x = std::boxed::Box::new(|x|x+1;);
  |                                     ^
3 | }
  | ^
  |
note: statement found outside of a block
 --> src/main.rs:2:41
  |
2 |     let _x = std::boxed::Box::new(|x|x+1;);
  |                                      ---^ this `;` turns the preceding closure into a statement
  |                                      |
  |                                      this expression is a statement because of the trailing semicolon
note: the closure body may be incorrectly delimited
 --> src/main.rs:2:35
  |
2 |     let _x = std::boxed::Box::new(|x|x+1;);
  |                                   ^^^^^^ this is the parsed closure...
3 | }
  | - ...but likely you meant the closure to end here
help: try adding braces
  |
2 ~     let _x = std::boxed::Box::new(|x| {x+1;);
3 ~ }}
  |

error: expected `;`, found `}`
 --> src/main.rs:2:44
  |
2 |     let _x = std::boxed::Box::new(|x|x+1;);
  |                                            ^ help: add `;` here
3 | }
  | - unexpected token

error: could not compile `playground` due to 3 previous errors

Desired output

error: closure bodies that contain statements must be surrounded by braces
 --> src/main.rs:2:37
  |
2 |     let _x = std::boxed::Box::new(|x|x+1;);
  |                                     ^
3 | }
  | ^
  |
note: statement found outside of a block
 --> src/main.rs:2:41
  |
2 |     let _x = std::boxed::Box::new(|x|x+1;);
  |                                      ---^ this `;` turns the preceding closure into a statement
  |                                      |
  |                                      this expression is a statement because of the trailing semicolon
help: try adding braces
  |
2 ~     let _x = std::boxed::Box::new(|x| {x+1;});
  |

error: could not compile `playground` due to 3 previous errors
@GoldsteinE GoldsteinE 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 Feb 12, 2023
@ohno418
Copy link
Contributor

ohno418 commented Feb 15, 2023

@rustbot claim

@estebank estebank added the A-parser Area: The lexing & parsing of Rust source code to an AST label Feb 17, 2023
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this issue Feb 23, 2023
…rmed-closure, r=davidtwco

parser: provide better suggestions and errors on closures with braces missing

We currently provide wrong suggestions and unhelpful errors on closure bodies with braces missing.

For example, given the following code:

```rust
fn main() {
    let _x = Box::new(|x|x+1;);
}
```

the current output is:

```
error: expected expression, found `)`
 --> ./main.rs:2:30
  |
2 |     let _x = Box::new(|x|x+1;);
  |                              ^ expected expression

error: closure bodies that contain statements must be surrounded by braces
 --> ./main.rs:2:25
  |
2 |     let _x = Box::new(|x|x+1;);
  |                         ^
3 | }
  | ^
  |
note: statement found outside of a block
 --> ./main.rs:2:29
  |
2 |     let _x = Box::new(|x|x+1;);
  |                          ---^ this `;` turns the preceding closure into a statement
  |                          |
  |                          this expression is a statement because of the trailing semicolon
note: the closure body may be incorrectly delimited
 --> ./main.rs:2:23
  |
2 |     let _x = Box::new(|x|x+1;);
  |                       ^^^^^^ this is the parsed closure...
3 | }
  | - ...but likely you meant the closure to end here
help: try adding braces
  |
2 ~     let _x = Box::new(|x| {x+1;);
3 ~ }}
  |

error: expected `;`, found `}`
 --> ./main.rs:2:32
  |
2 |     let _x = Box::new(|x|x+1;);
  |                                ^ help: add `;` here
3 | }
  | - unexpected token

error: aborting due to 3 previous errors
```

We got 3 errors, but all but the second are unnecessary or just wrong.

This commit allows outputting correct suggestions and errors. The above code would output like this:

```
error: closure bodies that contain statements must be surrounded by braces
 --> ./main.rs:2:25
  |
2 |     let _x = Box::new(|x|x+1;);
  |                         ^    ^
  |
note: statement found outside of a block
 --> ./main.rs:2:29
  |
2 |     let _x = Box::new(|x|x+1;);
  |                          ---^ this `;` turns the preceding closure into a statement
  |                          |
  |                          this expression is a statement because of the trailing semicolon
note: the closure body may be incorrectly delimited
 --> ./main.rs:2:23
  |
2 |     let _x = Box::new(|x|x+1;);
  |                       ^^^^^^ - ...but likely you meant the closure to end here
  |                       |
  |                       this is the parsed closure...
help: try adding braces
  |
2 |     let _x = Box::new(|x| {x+1;});
  |                           +    +

error: aborting due to previous error
```

Fixes rust-lang#107959.

r? diagnostics
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Feb 23, 2023
…rmed-closure, r=davidtwco

parser: provide better suggestions and errors on closures with braces missing

We currently provide wrong suggestions and unhelpful errors on closure bodies with braces missing.

For example, given the following code:

```rust
fn main() {
    let _x = Box::new(|x|x+1;);
}
```

the current output is:

```
error: expected expression, found `)`
 --> ./main.rs:2:30
  |
2 |     let _x = Box::new(|x|x+1;);
  |                              ^ expected expression

error: closure bodies that contain statements must be surrounded by braces
 --> ./main.rs:2:25
  |
2 |     let _x = Box::new(|x|x+1;);
  |                         ^
3 | }
  | ^
  |
note: statement found outside of a block
 --> ./main.rs:2:29
  |
2 |     let _x = Box::new(|x|x+1;);
  |                          ---^ this `;` turns the preceding closure into a statement
  |                          |
  |                          this expression is a statement because of the trailing semicolon
note: the closure body may be incorrectly delimited
 --> ./main.rs:2:23
  |
2 |     let _x = Box::new(|x|x+1;);
  |                       ^^^^^^ this is the parsed closure...
3 | }
  | - ...but likely you meant the closure to end here
help: try adding braces
  |
2 ~     let _x = Box::new(|x| {x+1;);
3 ~ }}
  |

error: expected `;`, found `}`
 --> ./main.rs:2:32
  |
2 |     let _x = Box::new(|x|x+1;);
  |                                ^ help: add `;` here
3 | }
  | - unexpected token

error: aborting due to 3 previous errors
```

We got 3 errors, but all but the second are unnecessary or just wrong.

This commit allows outputting correct suggestions and errors. The above code would output like this:

```
error: closure bodies that contain statements must be surrounded by braces
 --> ./main.rs:2:25
  |
2 |     let _x = Box::new(|x|x+1;);
  |                         ^    ^
  |
note: statement found outside of a block
 --> ./main.rs:2:29
  |
2 |     let _x = Box::new(|x|x+1;);
  |                          ---^ this `;` turns the preceding closure into a statement
  |                          |
  |                          this expression is a statement because of the trailing semicolon
note: the closure body may be incorrectly delimited
 --> ./main.rs:2:23
  |
2 |     let _x = Box::new(|x|x+1;);
  |                       ^^^^^^ - ...but likely you meant the closure to end here
  |                       |
  |                       this is the parsed closure...
help: try adding braces
  |
2 |     let _x = Box::new(|x| {x+1;});
  |                           +    +

error: aborting due to previous error
```

Fixes rust-lang#107959.

r? diagnostics
@bors bors closed this as completed in 8acbfe2 Feb 24, 2023
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The lexing & parsing of Rust source code to an AST T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants