Skip to content

Confusing error message with missing return #22216

Description

@mrmonday

The following code:

#![allow(dead_code)]

fn forgot_to_return() -> usize {
    while 4 > 3 {
        /* do something */
    }
}

fn main() {
    let _ = forgot_to_return();
}

Gives the error message:

<anon>:4:5: 6:6 error: mismatched types:
 expected `usize`,
    found `()`
(expected usize,
    found ()) [E0308]
<anon>:4     while 4 > 3 {
<anon>:5         /* do something */
<anon>:6     }
error: aborting due to previous error

Playpen: http://is.gd/0sudKI

This is confusing, since it looks like the type of either 4 or 3 is () - it is not clear that the actual error is that the while loop is being treated as the final expression in the function, and its type does match the return type of the function.

Activity

  1. mdinger commented on Feb 12, 2015

    @mdinger
    Contributor

    This gives the same error and might be arguably more clear, but not by much because the problem remains.

    fn forgot_to_return() -> usize {
        while true {}
    }

    What would a fix look like though? Should while and other similar keywords have special cases such as:

    <anon>:4:5: 6:6 error: a `while` loop expression of type `()` is being returned but `usize` is expected
    <anon>:4:5: 6:6 error: mismatched types:
     expected `usize`,
        found `()`
    (expected usize,
        found ()) [E0308]
    <anon>:4     while 4 > 3 {
    <anon>:5         /* do something */
    <anon>:6     }
    error: aborting due to previous error

    Maybe this:

    <anon>:4:5: 6:6 error: mismatched types:
     expected `usize`,
        found `()`
    (expected usize,
        found a `while` loop expression returning `()`) [E0308]
    <anon>:4     while 4 > 3 {
    <anon>:5         /* do something */
    <anon>:6     }
    error: aborting due to previous error

    I actually like the second better. I wasn't sure how a better error would look before this. Maybe the tip should be via a warning or a try this comment. It's less likely to be fixed if the fixed form isn't decided or clear.

  2. Xirdus commented on Feb 17, 2015

    @Xirdus

    I think it shouldn't be limited to particular keywords, but general - whenever it's about wrong return type, the error should read "mismatched return type (missing return?)" or something instead of the generic "mismatched types".

  3. mdinger commented on Feb 17, 2015

    @mdinger
    Contributor

    This isn't just restricted to function return types. These are just to highlight that when the expression is big, it's especially unclear what the problem is. It just looks like something is wrong with the while loop but it's not clear what.

    This isn't returning anything but has the same issue:

    fn main() {
        let _: usize = while 4 > 3 {
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
            let _ = 3;
        };
    }

    Output:

    <anon>:2:20: 33:6 error: mismatched types:
     expected `usize`,
        found `()`
    (expected usize,
        found ()) [E0308]
    <anon>:2     let _: usize = while 4 > 3 {
    <anon>:3         let _ = 3;
    <anon>:4         let _ = 3;
    <anon>:5         let _ = 3;
    <anon>:6         let _ = 3;
    <anon>:7         let _ = 3;
             ...
    error: aborting due to previous error
    playpen: application terminated with error code 101

    All this error states is that there is a mismatch on line 2 which includes a while loop. Where in this huge expression is the problem?


    Similarly, this doesn't work:

    fn main() {
        let x = 3;
        let _: usize = match x {
            0 => while true {
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
                let _ = 3;
            },
            _ => 3,
        };
    }
    <anon>:4:14: 35:10 error: mismatched types:
     expected `usize`,
        found `()`
    (expected usize,
        found ()) [E0308]
    <anon>:4         0 => while true {
    <anon>:5             let _ = 3;
    <anon>:6             let _ = 3;
    <anon>:7             let _ = 3;
    <anon>:8             let _ = 3;
    <anon>:9             let _ = 3;
             ...
    error: aborting due to previous error
    playpen: application terminated with error code 101

    I think nesting can make these even more unclear.

  4. steveklabnik commented on Mar 4, 2016

    @steveklabnik
    Contributor

    Triage: this diagnostic remains the same today.

  5. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Mar 9, 2017
  6. Mark-Simulacrum commented on May 10, 2017

    @Mark-Simulacrum
    Member

    Closing in favor of collective issue for this general problem: #41897.

  7. added a commit that references this issue on May 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-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