-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Pre-RFC: Add an Empty
type to libcore. Use it to replace the fn() -> !
syntax.
#1001
Comments
One other alternative is to keep the |
The advantage of the current built-in support for If we do want to add a library type instead of or in addition to it, I think it should be called |
The bottom type was removed in rust-lang/rust#14973, because of maintenance difficulty? I don't think it's very important for 1.0 though, requiring the user to provide a must-be-never-ending closure |
How often do you call a diverging function from a non-diverging function without using
And similarly |
I quite like this. Then the name |
It's only important because it would be a backwards-incompatible change. |
From an optimization perspective, the implementation of Bikeshed: Note that there exists (disclaimer: I wrote it) a crate with a similar type and helpers called void, whose code is here: https://github.com/reem/rust-void |
Also, a similar empty type used to exist in |
@canndrew: Why would it not be backwards-compatible (provided we choose to keep |
@llogiq I meant if the |
Agreed. Well, I think the |
Triage: Superseded by #1216 |
Summary
Add an
Empty
type to libcore. Use it to replace thefn() -> !
sytax.Motivation
See some previous discussion here: http://internals.rust-lang.org/t/should-be-a-type/1723 here: rust-lang/rust#20172 and here: rust-lang/rust#18414
Edit: @reem has already implemented a crate for this. See: https://github.com/reem/rust-void
A standard
Empty
type (ie. an enum with no variants) would be a useful addition to the standard library. One use case is if you need to implement a trait method that returnsResult<_, Err>
whereErr
is an associated type but you know that your implementation cannot fail. Currently, library authors can easily define their own empty types, but this will result in multiple libraries defining the same thing.Making diverging functions ordinary functions also allows them to be used in generic code. For example, it would allow functions that diverge to be passed as arguments to higher-order functions.
Removing
!
and replacing it with a plain ol' type will make Rust slightly simpler.Detailed design
Add this to libcore:
Add an
empty
lang item so that intrinsics likeabort
can return it. Make all methods that are currently marked as diverging (eg.panic
,abort
) returnEmpty
instead. Make thepanic!
macro expand tobegin_unwind(...).elim()
instead of justbegin_unwind(...)
to avoid users having to add the.elim()
themselves.Add a convenience method to
Result<T, Empty>
:Drawbacks
This change will require typing
.elim()
where previously someone wouldn't have had to. But only when calling a diverging function from a non-diverging function without using one of thepanic!
family macros. In the future, Rust's type checker could be improved to allow any type which is isomorphic toEmpty
to unify with any other type.It might make things like reachability checking more difficult. But it would be nice anyway if the compiler could detect unreachable code after code that produces an empty value.
!
used to be treated as a type though, but this was removed due to maintenance difficulties.Alternatives
Just add an
Empty
type tolibcore
but keep the seperate divergence syntax aswell.Name it
Never
as in "this value can never exist" or "this function can never return". Name itVoid
. However this is likely to confuse programmers from a C-family language background asVoid
is not()
. Name itBottom
. Name it something else.Unresolved questions
Is there time to make this change before 1.0?
The text was updated successfully, but these errors were encountered: