Skip to content
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

make noreturn type more like the "zero" type #3257

Closed
vi opened this issue Sep 19, 2019 · 5 comments · Fixed by #12462
Closed

make noreturn type more like the "zero" type #3257

vi opened this issue Sep 19, 2019 · 5 comments · Fixed by #12462
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@vi
Copy link

vi commented Sep 19, 2019

  • ?noreturn is not allowed instead of being void-equivalent (always null). Like u0 is currently void-equivalent.
  • Empty unions are disallowed instead of being noreturn-equivalent.
  • unreachable code error is too strict, preventing instantiating generic code with T=noreturn
  • Using noreturn for union variant does still allocate a tag for such variant

Java gets unit and zero types wrong. Rust gets unit and zero types (relatively) right. Zig gets unit type right, but zero type wrong. Shall it be fixed?

@andrewrk andrewrk added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Sep 20, 2019
@andrewrk andrewrk added this to the 0.6.0 milestone Sep 20, 2019
@andrewrk andrewrk changed the title noreturn type feels like a second class citizen in Zig make noreturn type more like the "zero" type Sep 20, 2019
@andrewrk andrewrk added the accepted This proposal is planned. label Oct 16, 2019
@andrewrk
Copy link
Member

Another use for this: anyerror!noreturn would be the return type of std.os.execve. When there is an explicit type, it could be used directly, e.g. anyerror, but when one wants to infer the type, !noreturn makes sense.

@daurnimator
Copy link
Collaborator

Empty unions are disallowed instead of being noreturn-equivalent.

I feel like this is the "right thing". @vi do you have an example use case for this one?

@vi
Copy link
Author

vi commented Oct 16, 2019

@daurnimator , Obvious one is codegenerated Zig code where union variants are filled in by automatic algorithm.

Special cased error because of something happens to be empty leads to special cases and workarounds in code generator (i.e. removing the type altogether or adding a dummy variant).

If empty unions definitions and (also empty) switch statements on those unions are allowed, less corner cases need to be considered in code generator.


Another case is temporary commenting out some code. Commenting out the last union variant leads to bigger reorganisation. Think of "trailing comma, but in the world of types".

@vi
Copy link
Author

vi commented Oct 16, 2019

@daurnimator

I feel like this is the "right thing"

Tagged union of 2 bools (union(enum) { var1: bool, var2: bool,}) has total 4 possible states. Remove var2 - now 2 possible states. Also remove var1 - now 0 possible states. Just like noreturn. So allowing it and making it like noreturn (at least with respect to code generation) seems like the right thing. Other noreturn features (like convertability to any other type) are probably not good although.

You need 2 switch branches to handle the original union. You need 1 branch to handle the union without var2. You need 0 switch branches to handle the final empty union. For code generation, that switch is just unreachable.

@andrewrk andrewrk modified the milestones: 0.6.0, 0.7.0 Feb 13, 2020
@tadeokondrak
Copy link
Contributor

tadeokondrak commented May 5, 2020

Rust originally special cased ! in return position, but then made it a real type:
https://github.com/rust-lang/rfcs/blob/master/text/1216-bang-type.md
Swift originally had a @noreturn attribute but changed it to its own type,
https://github.com/apple/swift-evolution/blob/master/proposals/0102-noreturn-bottom-type.md

In both of these cases, the languages already had a concept of an "uninhabited type", such as an enum with zero variants. I think Zig should also make empty enums/unions work, and make noreturn equivalent to them (and maybe rename it to never?).

noreturn already coerces to any type, but making empty enums and unions do that would be a footgun. Empty enums and unions should be convertable to noreturn by switching on them: switch (value) {}.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants