Repository navigation
Arms permitted when matching on uninhabited types #55123
Description
Activity
The second issue is a direct result of the first, where "number of arms" is treated as a heuristic for divergence, rather than the type of the expression (this could be an issue in the future with regards to an explicit
!pattern):
https://github.com/rust-lang/rust/blob/3b88a54ebcf1d704fddd464e9d5225530cfb475b/src/librustc_typeck/check/_match.rs#L611-L615- addedA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.
on Oct 16, 2018 This is due to:
I think the solution here is to stabiliserust/src/librustc_mir/hair/pattern/_match.rs
Lines 374 to 380 in 0982be7
fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { if self.tcx.features().exhaustive_patterns { self.tcx.is_ty_uninhabited_from(self.module, ty) } else { false } } exhaustive_patterns.Reacted by Nadrieril- addedA-exhaustiveness-checkingRelating to exhaustiveness / usefulness checking of patternsRelating to exhaustiveness / usefulness checking of patternsC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.C-bugCategory: This is a bug.Category: This is a bug.and removedC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.
on May 22, 2020 I don't think
exhaustive_patternswould fix the second issue: it would detect the arm as unreachable, but afaik that bit of match checking does not count towards counting the match as divergent.The second issue got fixed in #78995. I'm wondering about the first one: is matching on an empty enum very different from getting a value of an empty type as input? My hunch would be that if we lint any code after
match x {}to be unreachable, why not lint the whole function body afterfn foo(x: Void)as unreachable? Is there a particular reason that either is more natural/useful for an user?pub enum Void {} pub fn foo(x: Void) { let _ = (); // Frankly this also could be warned as unreachable. match x {}; let _ = (); // This could be warned as unreachable, but isn't. }
I agree that these are essentially the same issue. I actually submitted a PR a couple of years ago to address this, by making the uninhabitedness checking more eager (see #47291), but parts of it were split out to err on the side of being more conservative. I can't quite remember the status: probably in order to make these changes, there would need to be a discussion into how eagerly one wants to mark unreachable code based on uninhabited types. Probably this issue can be closed, and potentially a new one opened to explore reachability based on inhabitedness.
It looks like the
let _xyzline isn't linted as unreachable because MIR for it is not generated (even in debug mode).pub enum Void {} pub fn foo(x: Void) { match x { _ => {} // This arm shouldn't be permitted. }; let _xyz = (); // This should be warned as unreachable, but isn't. }
Not sure if related, but I encountered two surprising error:
enum Empty {} fn foo(x: &Empty) { match x {} // ERROR: missing match arm. }
enum Empty1 {} enum Empty2 {} fn foo(x: (Empty1, Empty2)) { match x {} // ERROR: missing match arm. }
I have to add a
_ => {}arm for the code to compile.- Reacted by EFanZh
- addedA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.and removedA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.
on Dec 21, 2024
There seem to be two issues here:
On the other hand, the following code does warn: