Repository navigation
Description
What is being stabilized
-
!is now a full-fledged type and can now be used in any type position (eg. RFC 1216). The!type can coerce into any other type, see https://github.com/rust-lang/rust/tree/master/src/test/run-fail/adjust_never.rs for an example. -
Type inference will now default unconstrained type variables to
!instead of(). Theresolve_trait_on_defaulted_unitlint has been retired. An example of where this comes up is if you have something like:// We didn't specify the type of `x`. Under some circumstances, type inference // will pick a type for us rather than erroring let x = Deserialize::deserialize(data);
Under the old rules this would deserialize a
(), whereas under the new rules it will deserialize a!. -
The
never_typefeature gate is stable, although some of the behaviours it used to gate now live behind the newexhaustive_patternsfeature gate (see below).
What is not being stabilized
-
Exhaustive pattern-matching for uninhabited types. eg.
let x: Result<u32, !> = ...; let Ok(y) = x;
This code will still complain that
Ok(_)is a refutable pattern. This can be fixed by using theexhaustive_patternsfeature gate. See RFC 1872 for progress on this issue. See https://github.com/rust-lang/rust/tree/master/src/test/ui/feature-gate-exhaustive-patterns.rs for the testcase which confirms that this behaviour is still gated.
Activity
nikomatsakis commentedon Mar 12, 2018
Note decision was made to stabilize here.
scottmcm commentedon Mar 12, 2018
I had a thought that I think needs to be resolved in the same release as this stabilization: Is there an existing stable uninhabited type in
core/stdthat we want to make an alias for!? (AFAIK we could only do this for one of them, since coherence.)The one that comes to mind for me is
std::string::ParseError...nikomatsakis commentedon Mar 13, 2018
@scottmcm I don't think there's a ton of motivation to do that -- I believe that, when all is said and done, empty enums and
!will behave quite similarly in most ways, apart from coercions. Notably in matches.nikomatsakis commentedon Mar 13, 2018
Still, interesting thought. Maybe nicer just for simplicity?
cc @rust-lang/libs -- see @scottmcm's suggestion above about making uninhabited types like
string::ParseErroran alias for!sfackler commentedon Mar 13, 2018
I had always assumed that all of the void errors would turn into type aliases for
!but I hadn't thought of the coherence issue. How many do we actually have? It seems like it may not be worth changing just one of many.alexcrichton commentedon Mar 13, 2018
Yeah I was also personally under the impression that we'd change the types to be aliases and run crater to see if it actually had any fallout (as at the time I don't think we expected much)
nikomatsakis commentedon Mar 14, 2018
Well, I just r+'d the
!stabilization PR, so we have until the next release. =)scottmcm commentedon Mar 15, 2018
Well I only found 3 (ParseError, unstable Infallible, and new-for-1.26 ParsePathError) so PR up: #49039
Auto merge of #49039 - scottmcm:never-aliases, r=<try>
3 remaining items
nikomatsakis commentedon Apr 11, 2018
@canndrew looking at @mitsuhiko's issue, and just thinking generally -- I was wondering -- what is the classic example of why fallback to
()would "have" to be changed? That is, if we continued to fallback to(), but still added!, it would certainly avoid that sort of problem -- and falling back to!is not optimal, given that there are cases where the fallback occurs to a type variable that winds up influencing "live" code (the intention of course is otherwise, but it's hard to prevent leaks, as we've found).nikomatsakis commentedon Apr 11, 2018
Nominating for brief lang-team discussion around this final point
SimonSapin commentedon Apr 11, 2018
For what it’s worth the fallback change caused some previously-valid
unsafecode to go Very Wrong: rust-windowing/winit#428, servo/servo#20474 (comment).In short: generic FFI bindings in the
objccrate end up returningOk(x: R)whereRis an unconstrained type parameter whose inference changed from()to!. So now (to simplify) theResult<!, String>::Okvalue is incorrectly assumed to beErr, and on drop we deallocate aStringwhose pointer is made of padding bytes. jemalloc is not amused. The fix is changing statements likesend!(…);to force the return type:let () = send!(…);nikomatsakis commentedon Apr 11, 2018
@SimonSapin ah yes thanks for raising that
nikomatsakis commentedon Apr 12, 2018
Cross-posted my question to the main tracking issue, and added a few details. That seems like a better place to have this conversation.
Update attributes for latest Rust nightly.
SimonSapin commentedon Dec 20, 2018
Should this be closed? The last comment pre-dates #50121 and now #57012.
pnkfelix commentedon Dec 21, 2018
closing since we have started a new round of stabilization in #57012 and so we should try to capture all concerns and other threads of conversation there.
Add `impl From<!> for Infallible`
Add explicit `()` return types for msg_send!
doc test fix: use explicit type annotation to force correct inference
Rustのバージョンの差により、型の明示が必要になってたため、注釈を追加。