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

Type error for loops in a non-() position moves to the break statement #51669

Closed
Manishearth opened this issue Jun 20, 2018 · 5 comments
Closed
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-inference Area: Type inference

Comments

@Manishearth
Copy link
Member

Rust has support for break within loop returning a value:

let x = loop {
 // ...
 break 5;
}

This is a relatively less-known feature.

If your loop is in a position where a type other than unit is expected, breaks in the loop may get a rather weird error (playpen)

fn foo() -> u8 {
    loop {
        // ...
        if true {
            break;
        }
        // ...
    }
}
error[E0308]: mismatched types
 --> src/main.rs:7:13
  |
7 |             break;
  |             ^^^^^ expected (), found u8
  |
  = note: expected type `()`
             found type `u8`

This error makes sense if you know that break can take a value, but most people don't, and this makes it kinda confusing. We should have better diagnostics here, perhaps move the primary error to the loop itself and add a note to the break, or vice versa.

(found by @jubitaneja)

@Manishearth Manishearth added A-diagnostics Area: Messages for errors, warnings, and lints A-inference Area: Type inference labels Jun 20, 2018
@jubitaneja
Copy link

Thanks, @Manishearth for teaching me this cool trick! Breaking with a value is really useful.

@oli-obk
Copy link
Contributor

oli-obk commented Jun 21, 2018

That type error is backwards. We are expecting a u8, nothing in your example supplies a u8

@oli-obk
Copy link
Contributor

oli-obk commented Jun 21, 2018

Also I think the error is exactly where it should be, but we should definitely add some explanation. Value-break is probably not the only place where a type mismatch error could benefit from some additional notes

Centril added a commit to Centril/rust that referenced this issue Aug 9, 2019
Tweak mismatched types error

- Change expected/found for type mismatches in `break`
- Be more accurate when talking about diverging match arms
- Tweak wording of function without a return value
- Suggest calling bare functions when their return value can be coerced to the expected type
- Give more parsing errors when encountering `foo(_, _, _)`

Fix rust-lang#51767, fix rust-lang#62677, fix rust-lang#63136, cc rust-lang#37384, cc rust-lang#35241, cc rust-lang#51669.
@estebank
Copy link
Contributor

That type error is backwards. We are expecting a u8, nothing in your example supplies a u8

Handled in #63337.

Also I think the error is exactly where it should be, but we should definitely add some explanation. Value-break is probably not the only place where a type mismatch error could benefit from some additional notes

If that is so, then this ticket should be closed when that PR is merged. Otherwise we can keep open exclusively to point at the enclosing loop when appropriate.

Centril added a commit to Centril/rust that referenced this issue Aug 10, 2019
Tweak mismatched types error

- Change expected/found for type mismatches in `break`
- Be more accurate when talking about diverging match arms
- Tweak wording of function without a return value
- Suggest calling bare functions when their return value can be coerced to the expected type
- Give more parsing errors when encountering `foo(_, _, _)`

Fix rust-lang#51767, fix rust-lang#62677, fix rust-lang#63136, cc rust-lang#37384, cc rust-lang#35241, cc rust-lang#51669.
Centril added a commit to Centril/rust that referenced this issue Aug 10, 2019
Tweak mismatched types error

- Change expected/found for type mismatches in `break`
- Be more accurate when talking about diverging match arms
- Tweak wording of function without a return value
- Suggest calling bare functions when their return value can be coerced to the expected type
- Give more parsing errors when encountering `foo(_, _, _)`

Fix rust-lang#51767, fix rust-lang#62677, fix rust-lang#63136, cc rust-lang#37384, cc rust-lang#35241, cc rust-lang#51669.
@estebank
Copy link
Contributor

Current output:

error[E0308]: mismatched types
 --> src/main.rs:7:13
  |
4 | fn foo() -> u8 {
  |             -- expected `u8` because of return type
...
7 |             break;
  |             ^^^^^
  |             |
  |             expected `u8`, found `()`
  |             help: give it a value of the expected type: `break 42`

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-inference Area: Type inference
Projects
None yet
Development

No branches or pull requests

4 participants