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

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 opened this issue Sep 24, 2020 · 1 comment · Fixed by #77317
Assignees
Labels
A-control-flow Area: Control flow C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@adlerd
Copy link

adlerd commented Sep 24, 2020

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.

@adlerd adlerd added the C-bug Category: This is a bug. label Sep 24, 2020
@jyn514 jyn514 added A-control-flow Area: Control flow T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 24, 2020
@varkor
Copy link
Member

varkor commented Sep 28, 2020

Similarly, the following doesn't work:

let loop_value = loop { break loop {} };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-control-flow Area: Control flow C-bug Category: This is a bug. 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