-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Incorrect "unreachable pattern" warning. #70372
Comments
Looks like this was injected in 1.41.0, ostensibly in the exhaustiveness checking refactorings. |
Hey Cleanup Crew ICE-breakers! This bug has been identified as a good cc @AminArria @chrissimpkins @contrun @DutchGhost @elshize @ethanboxx @h-michael @HallerPatrick @hdhoang @hellow554 @imtsuki @jakevossen5 @kanru @KarlK90 @LeSeulArtichaut @MAdrianMattocks @matheus-consoli @mental32 @nmccarty @Noah-Kennedy @pard68 @PeytonT @pierreN @Redblueflame @RobbieClarken @RobertoSnap @robjtede @SarthakSingh31 @senden9 @shekohex @sinato @spastorino @turboladen @woshilapin @yerke |
The relevant code is in fn check_arms<'p, 'tcx>(
cx: &mut MatchCheckCtxt<'p, 'tcx>,
arms: &[(&'p super::Pat<'tcx>, HirId, bool)],
) -> Matrix<'p, 'tcx> {
let mut seen = Matrix::empty();
let mut catchall = None;
for (arm_index, (pat, id, has_guard)) in arms.iter().copied().enumerate() {
let v = PatStack::from_pattern(pat);
match is_useful(cx, &seen, &v, LeaveOutWitness, id, true) {
NotUseful => { ... } // Elided, this branch should not be taken in this case.
Useful(unreachable_subpatterns) => {
for pat in unreachable_subpatterns {
unreachable_pattern(cx.tcx, pat.span, id, None);
}
}
UsefulWithWitness(_) => bug!(),
}
if !has_guard {
seen.push(v);
if catchall.is_none() && pat_is_catchall(pat) {
catchall = Some(pat.span);
}
}
}
seen
} From the point of exhaustiveness checking this algorithm is correct, but not from a linting POV in the presence of guards. Previously, before the or-patterns reform, we merely interpreted each To fix this, presumably we have to propagate |
In case this is still relevant.. I went trying out regressed nightly: nightly-2019-12-04 |
I'm going to assume we're ok with not detecting match (3,42) {
(a, _) | (a, _) if a > 10 => {println!("{}", a)}
_ => ()
} as redundant, otherwise we violate one of the assumptions of match checking, namely that variables and wildcards behave identically, and that's a whole other can of worms.
Agreed. Specifically, what we want to avoid is adding to the matrix any pattern that is under a match guard. The code in
is_under_guard bool to is_useful (recursively) should do the trick.@Centril (or anyone really) would you mind trying that ? 👼 Two more test cases to be sure we're doing it right: match Some((3,42)) {
Some((a, _)) | Some((_, a)) if a > 10 => {println!("{}", a)}
_ => ()
}
match Some((3,42)) {
Some((a, _) | (_, a)) if a > 10 => {println!("{}", a)}
_ => ()
} |
With such clear instructions, this looks like a good issue for beginners! I'll add the labels. |
Hi, I want to take this I understand the solution explained by @Nadrieril, but have one question regarding check_not_useful because it also calls |
@rustbot assign @AminArria |
Absolutely ! |
@AminArria Thanks for tackling this. :) I think it would also be neat to add some comments on Best of luck! |
👍 -- that seems like quite a reasonable tradeoff for what is a rare occurrence. :) |
I don't think this is any more readable, or safe, than a |
…arning, r=Centril,Nadrieril,varkor Fix incorrect pattern warning "unreachable pattern" Fixes rust-lang#70372 Added `is_under_guard` parameter to `_match::is_useful` and only add it to the matrix if `false` Tested with: ```rust #![feature(or_patterns)] fn main() { match (3,42) { (a,_) | (_,a) if a > 10 => {println!("{}", a)} _ => () } match Some((3,42)) { Some((a, _)) | Some((_, a)) if a > 10 => {println!("{}", a)} _ => () } match Some((3,42)) { Some((a, _) | (_, a)) if a > 10 => {println!("{}", a)} _ => () } } ```
Not much to comment about. The supposedly “unreachable” pattern is obviously reached.
(Playground)
Output:
Errors:
This issue has been assigned to @AminArria via this comment.
The text was updated successfully, but these errors were encountered: