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

Bad suggestion on missing block inside of a closure #107959

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 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 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
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 A-parser Area: The 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