Skip to content

rustc does not recognize a return inside a break expression for purposes of checking that every code path has the function return type #77156

Closed
@adlerd

Description

@adlerd

I tried this code:

fn test() -> i32 {
    let loop_value = loop { break (return 5); };
}
fn main() {
    println!("{}", test());
}

I expected that this would compile. Instead rustc says (on 1.48.0 nightly 2020-09-23):

error[E0308]: mismatched types
 --> src/main.rs:1:14
  |
1 | fn test() -> i32 {
  |    ----      ^^^ expected `i32`, found `()`
  |    |
  |    implicitly returns `()` as its body has no tail or `return` expression

As a sanity check, I also tested this:

fn test() -> i32 {
    let loop_value = loop { break (return 5); };
    return 0;
}
fn main() {
    println!("{}", test());
}

This compiles and when run prints 5, indicating that that expression is indeed the place the function returns. Looking at the function it's also clearly an unconditionally reached return. Compare

fn test() -> i32 {
    let loop_value = loop { return 5; };
}
fn main() {
    println!("{}", test());
}

which also compiles and runs without error.

On the same theme, I was worried that this might erroneously typecheck:

fn test() -> i32 {
    let loop_value = loop { break (return Some(5)); };
    return 0;
}
fn main() {
    println!("{}", test());
}

but it doesn't, indicating the compiler is quite cognizant that the value returned in this position has to unify with the return type.

Metadata

Metadata

Assignees

Labels

A-control-flowArea: Control flowC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions