Tracking Issue for Rust 2024: Make !
fall back to !
· Issue #123748 · rust-lang/rust (original) (raw)
This is a tracking issue for the change to make fallback fall back from !
to !
(rather than to ()
) in Rust 2024. This is part of a plan that leads to eventually stabilizing the never (!
) type.
What this change means
This change means that ! does not spontaneously decay to (). For example, consider this code:
fn print_return_type(_: fn() -> R) {
println!("{}
", std::any::type_name::());
}
print_return_type(|| todo!()); // before this change: prints ()
// after this change: prints !
todo!()
"returns" !
, but before this change this !
decayed to ()
when being returned from the closure. In general, this can happen at any coercion site, if the type is not set by something else.
If your code is broken with errors like `!: Trait` is not satisfied
, then you need to make sure the type is specified explicitly. For example:
fn create_zst<T: From<()>>() -> T { ().into() }
if condition { create_zst() } else { return };
Before this change !
from return
decays to ()
, meaning that create_zst
will also return ()
, and since ()
implements From<()>
this was fine. With this change however, !
from return
keeps being !
and inference makes create_zst
also return !
, however !
does not implement From<()>
causing a compilation error.
The easiest fix is to specify the type explicitly:
if condition { create_zst::<()>() } else { return };
However, this can also be a sign that you don't care what the type is, and maybe the better solution is to refactor the code.
Also note that this "create something or return" pattern can also be caused by ?
with code like this:
Because deserialize
's output type is not bound to be anything, it gets inferred from ?
's desugaring that includes a return
. (there is a separate initiative to stop ?
from affecting inference like this: #122412)
About tracking issues
Tracking issues are used to record the overall progress of implementation. They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions. A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature. Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Steps
- Implement in nightly Rust 2024.
- Add migration lints.
- Add a lint against fallback affecting
unsafe
functions.
* Discussion.
* Add a lint against never type fallback affecting unsafe code #123939
* Never type unsafe lint improvements #125282 - N/A: Add a lint against fallback affecting non-diverging variables in weird ways /
?
guiding inference.
* Discussion.
* Reason for N/A. - Add a lint against fallback to unit being required for code to compile.
* Discussion.
* Implement lint for obligations broken by never type fallback change #125289
- Add a lint against fallback affecting
- Add documentation to the standard library.
- N/A: Add documentation to the dev guide.
- See the instructions.
- N/A: Add documentation to the reference.
- See the instructions.
- Add documentation to the edition guide.
- Ensure ready for Rust 2024 stabilization.
Unresolved Questions
- Decide whether to make the Add a lint against never type fallback affecting unsafe code #123939 lint (against fallback affecting a generic that is passed to an
unsafe
function)deny-by-default
or a hard error in Rust 2024.
Related
- [experiment] Turn off never type fallback #122955
- [experiment] Set never type fallback = ! #123482
- Edition 2024: Make ! fall back to ! #123508
- Correctly change type when adding adjustments on top of NeverToAny #123571
- Add a lint against never type fallback affecting unsafe code #123939
- Document never type fallback in !'s docs #124419
- Never type unsafe lint improvements #125282
- Implement lint for obligations broken by never type fallback change #125289
- Point out failing never obligation for DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK #126367
- Should we make lint against fallback affecting unsafe code a hard error in Rust 2024? #126693
- Make NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE a deny-by-default lint in edition 2024 #126881
- Add a section for the never type change in e2024 edition-guide#310