Skip to content

Tracking issue for coerce_never compatibility lint #46325

@arielb1

Description

@arielb1

This is the summary issue for the coerce_never future-compatibility warning and other related errors. The goal of this page is describe why this change was made and how you can fix code that is affected by it. It also provides a place to ask questions or register a complaint if you feel the change should not be made. For more information on the policy around future-compatibility warnings, see our breaking change policy guidelines.

What is the warning for?

In Rust, if the end of a block can't be reached from the block's start (because the block contains an infinite loop, panic, or early return), you can leave out the trailing expression (which can't be reached in that case) at the end of the block, and then the block can return an arbitrary type.

For example, you can write this and give x every Sized type.

fn example() {
    let x: AnyTypeYouWant = {
        if i_feel_like_panicking {
            panic!();
        } else {
            return;
        }
        // the end of this block can't be reached. No trailing expression,
        // and you can return any type you want.
    };
}

However, if you do write a trailing expression for the block, then it has to have the correct type - this is required to avoid some weird type inference problems:

fn example() {
    let x: u8 = {
        panic!();
        1u32 //~ ERROR mismatched types
    };
}

This makes for a simple, consistent system.

However, in previous versions of the compiler, you could let the trailing expression have the type !:

fn example_will_break() -> ! {
    panic!();
    1u32 // unreachable expression
}

// or more practically (here the *trailing expression* can't return)
fn example_will_break() -> ! {
    Some(panic!()) // Option<_> is converted to !
}

That was an inconsistency, as it only worked for the type ! specifically, rather than any other type (not even (), or on the other side, other empty enums). Therefore, it is being removed in preparation for ! to be stabilized.

If you encounter this error, you can always fix it by creating a block with no trailing expression in the place of the type error, which as above can return arbitrary types:

fn example_fixes() -> ! {
    Some(panic!()); // now with more semicolons
    // no trailing expression, this can return any type!
}

When will this warning become a hard error?

At the beginning of each 6-week release cycle, the Rust compiler team will review the set of outstanding future compatibility warnings and nominate some of them for Final Comment Period. Toward the end of the cycle, we will review any comments and make a final determination whether to convert the warning into a hard error or remove it entirely.

Metadata

Metadata

Assignees

No one assigned

    Labels

    B-unstableBlocker: Implemented in the nightly compiler and unstable.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-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