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

Detect type mismatch due to loop that might never iterate with 3 or more return statements #100285

Closed
lyming2007 opened this issue Aug 8, 2022 · 2 comments · Fixed by #123125
Closed
Assignees
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-verbose Diagnostics: Too much output caused by a single piece of incorrect code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@lyming2007
Copy link

lyming2007 commented Aug 8, 2022

Given the following code:

fn foo(n: i32) -> i32 {
    for i in 0..0 {
       if n < 0 {
        return i;
        } else if n < 10 {
          return 1;
        } else if n < 20 {
          return 2;
        } else if n < 30 {
          return 3;
        } else if n < 40 {
          return 4;
        } else {
          return 5;
        }

    }
}

fn main() {}

The current output is:

error[E0308]: mismatched types
  --> main.rs:2:5
   |
1  |   fn foo(n: i32) -> i32 {
   |                     --- expected `i32` because of return type
2  | /     for i in 0..0 {
3  | |        if n < 0 {
4  | |         return i;
5  | |         } else if n < 10 {
...  |
16 | |
17 | |     }
   | |_____^ expected `i32`, found `()`
   |
note: the function expects a value to always be returned, but loops might run zero times
  --> main.rs:2:5
   |
2  |     for i in 0..0 {
   |     ^^^^^^^^^^^^^ this might have zero elements to iterate on
3  |        if n < 0 {
4  |         return i;
   |         -------- if the loop doesn't execute, this value would never get returned
5  |         } else if n < 10 {
6  |           return 1;
   |           -------- if the loop doesn't execute, this value would never get returned
7  |         } else if n < 20 {
8  |           return 2;
   |           -------- if the loop doesn't execute, this value would never get returned
9  |         } else if n < 30 {
10 |           return 3;
   |           -------- if the loop doesn't execute, this value would never get returned
11 |         } else if n < 40 {
12 |           return 4;
   |           -------- if the loop doesn't execute, this value would never get returned
13 |         } else {
14 |           return 5;
   |           -------- if the loop doesn't execute, this value would never get returned
   = help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility

error: aborting due to previous error

Ideally the output should look like:

error[E0308]: mismatched types
  --> main.rs:2:5
   |
1  |   fn foo(n: i32) -> i32 {
   |                     --- expected `i32` because of return type
2  | /     for i in 0..0 {
3  | |        if n < 0 {
4  | |         return i;
5  | |         } else if n < 10 {
...  |
16 | |
17 | |     }
   | |_____^ expected `i32`, found `()`
   |
note: the function expects a value to always be returned, but loops might run zero times
  --> main.rs:2:5
   |
2  |     for i in 0..0 {
   |     ^^^^^^^^^^^^^ this might have zero elements to iterate on
3  |        if n < 0 {
4  |         return i;
   |         -------- if the loop doesn't execute, this value would never get returned
5  |         } else if n < 10 {
6  |           return 1;
   |           -------- if the loop doesn't execute, this value would never get returned
7  |         } else if n < 20 {
8  |           return 2;
   |           -------- if the loop doesn't execute, this value would never get returned
9  |         } else if n < 30 {
10 |           return 3;
   |           -------- if the loop doesn't execute, this value would never get returned
   = note: if the loop doesn't execute, 2 other values would never get returned 
   = help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility

error: aborting due to previous error

@lyming2007 lyming2007 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 Aug 8, 2022
@lyming2007
Copy link
Author

lyming2007 commented Aug 8, 2022

@rustbot claim

@lyming2007
Copy link
Author

#100338
@estebank please take a look if you have time

@estebank estebank added the D-verbose Diagnostics: Too much output caused by a single piece of incorrect code. label Nov 22, 2023
bors added a commit to rust-lang-ci/rust that referenced this issue Apr 19, 2024
…iters-2, r=estebank

Remove suggestion about iteration count in coerce

Fixes rust-lang#122561

The iteration count-centric suggestion was implemented in PR rust-lang#100094, but it was based on the wrong assumption that the type mismatch error depends on the number of times the loop iterates. As it turns out, that is not true (see this comment for details: rust-lang#122679 (comment))

This PR attempts to remedy the situation by changing the suggestion from the one centered on iteration count to a simple suggestion to add a return value.

It should also fix rust-lang#100285 by simply making it redundant.
@bors bors closed this as completed in 06e88c3 May 5, 2024
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 D-verbose Diagnostics: Too much output caused by a single piece of incorrect code. 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.

2 participants