-
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
Fix the handling of uninhabited types in pattern matching. #1872
Conversation
Copying from the internal threads, there are a few desirable properties of
The problem is: let x: &! = get();
match x {
} From (1), we also get unsafe {
let x: &! = get();
match x {
}
} On the other hand, we also want this to be non-UB - aka (3) unsafe {
let x: &Whatever = get();
match x {
y => println!("hi {:?}", y as *const _)
}
} Because of (4), this is equivalent to unsafe {
let x: &! = get();
match x {
y => println!("hi {:?}", y as *const _)
}
} Which contradicts (5) |
I think this RFC proposal denies (5) while keeping (1)-(4). @nikomatsakis has a good argument for (5), but I'll prefer that he present it. |
My alternative of https://internals.rust-lang.org/t/recent-change-to-make-exhaustiveness-and-uninhabited-types-play-nicer-together/4602/57?u=ericson2314 where |
To repeat this in the thread, the proposal is: unsafe {
let x: &! = get();
match x {
_ /* no arm needed */,
}
} I consider that !(2), but it requires bikesheddy syntax. |
@arielb1 hmm? In my alternative one would need to do: unsafe {
let x: &! = get();
match x {
&_, // no arm needed
}
} The idea is by bothering to pattern match down to the trivially uninhabited case, [unsafe | all, depending on what we want] code is asserting that the branch is unreachable. unsafe {
let x: &! = get();
let y = match x { y => y };
println!("I'm alive!"); // not dead code, because unsafe + insufficiently deep match
} |
Hmm, I just realized if one has a tuple of Examples:
This is great for those coming from Haskell [haha, what a pedagogical priority], because if you really really drunkenly squint, asserting uninhabitedness is like forcing a binding (with !), and and @arielb1's trap representations are like the bottom value. |
```rust | ||
let t = match never_fails() { | ||
Ok(t) => t, | ||
Err(e) => match {}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be match e {}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks.
I would prefer to go with what's proposed in the RFC because it's consistent with how we match on non-empty sum types and because forcing users to handle trap representations in matches kinda defeats the point of having types. However, there's no reason why we couldn't do both the RFC and your suggestion. There's a Pre-RFC proposing to generalise the use of match x: u32 {
0 | 1 | 2 => ..., // match on 3 different values
4 | 5 => ..., // match on 2 different values
6 => ..., // match on 1 value
! => ..., // match on 0 values. Because this match is unsatisfiable
// the arm (everything right of and uncluding =>) is optional
7 | ! => ..., // only matches 7
_ => ...,
} However if people weren't forced to use this then it would be pretty pointless. |
@canndrew yeah I prefer yours too, but I also prefer mine to the status quo so consider it a hedge :). Also, thank you for the identify-of-| language! I was looking for something like that. I think that line of thinking will ultimately clarify what (5) is really about. |
Hmm the clarity of ! might especially be good in irrefutable patterns (lets, function parameters). |
So.... what's happening with this? I'm hearing rumors that decisions have been made here and there about how to handle empty patters, |
@canndrew Oof, my apologies for the total silence from the lang team. I'm going to nominate this RFC for discussion so we can bring it back into cache and try to suggest a trajectory. |
@aturon That's fine, I recognize this isn't exactly a high priority. |
@rfcbot fcp postpone We discussed this in the @rust-lang/lang meeting today. We would very much like to see progress towards stabilizing |
Team member @nikomatsakis has proposed to postpone this. The next step is review by the rest of the tagged teams: No concerns currently listed. Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
1 similar comment
🔔 This is now entering its final comment period, as per the review above. 🔔 |
The final comment period is now complete. |
Closing as postponed. Thanks @canndrew! |
Rendered