Skip to content

Commit 1c1bec2

Browse files
committed
Remove top-level or-pattern hack
1 parent ef087d9 commit 1c1bec2

File tree

3 files changed

+85
-114
lines changed

3 files changed

+85
-114
lines changed

src/librustc_mir/hair/pattern/check_match.rs

+80-102
Original file line numberDiff line numberDiff line change
@@ -139,39 +139,22 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
139139
MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| {
140140
let mut have_errors = false;
141141

142-
let inlined_arms: Vec<(Vec<_>, _)> = arms
142+
let inlined_arms: Vec<_> = arms
143143
.iter()
144144
.map(|arm| {
145-
(
146-
// HACK(or_patterns; Centril | dlrobertson): Remove this and
147-
// correctly handle exhaustiveness checking for nested or-patterns.
148-
match &arm.pat.kind {
149-
hir::PatKind::Or(pats) => pats,
150-
_ => std::slice::from_ref(&arm.pat),
151-
}
152-
.iter()
153-
.map(|pat| {
154-
let mut patcx = PatCtxt::new(
155-
self.tcx,
156-
self.param_env.and(self.identity_substs),
157-
self.tables,
158-
);
159-
patcx.include_lint_checks();
160-
let pattern = cx
161-
.pattern_arena
162-
.alloc(expand_pattern(cx, patcx.lower_pattern(&pat)))
163-
as &_;
164-
if !patcx.errors.is_empty() {
165-
patcx.report_inlining_errors(pat.span);
166-
have_errors = true;
167-
}
168-
(pattern, &**pat)
169-
})
170-
.collect(),
171-
arm.guard.as_ref().map(|g| match g {
172-
hir::Guard::If(ref e) => &**e,
173-
}),
174-
)
145+
let mut patcx = PatCtxt::new(
146+
self.tcx,
147+
self.param_env.and(self.identity_substs),
148+
self.tables,
149+
);
150+
patcx.include_lint_checks();
151+
let pattern: &_ =
152+
cx.pattern_arena.alloc(expand_pattern(cx, patcx.lower_pattern(&arm.pat)));
153+
if !patcx.errors.is_empty() {
154+
patcx.report_inlining_errors(arm.pat.span);
155+
have_errors = true;
156+
}
157+
(pattern, &*arm.pat, arm.guard.is_some())
175158
})
176159
.collect();
177160

@@ -399,95 +382,90 @@ fn pat_is_catchall(pat: &Pat) -> bool {
399382
// Check for unreachable patterns
400383
fn check_arms<'p, 'tcx>(
401384
cx: &mut MatchCheckCtxt<'p, 'tcx>,
402-
arms: &[(Vec<(&'p super::Pat<'tcx>, &hir::Pat)>, Option<&hir::Expr>)],
385+
arms: &[(&'p super::Pat<'tcx>, &hir::Pat, bool)],
403386
source: hir::MatchSource,
404387
) -> Matrix<'p, 'tcx> {
405388
let mut seen = Matrix::empty();
406389
let mut catchall = None;
407-
for (arm_index, &(ref pats, guard)) in arms.iter().enumerate() {
408-
for &(pat, hir_pat) in pats {
409-
let v = PatStack::from_pattern(pat);
410-
411-
match is_useful(cx, &seen, &v, LeaveOutWitness, hir_pat.hir_id) {
412-
NotUseful => {
413-
match source {
414-
hir::MatchSource::IfDesugar { .. } | hir::MatchSource::WhileDesugar => {
415-
bug!()
416-
}
417-
418-
hir::MatchSource::IfLetDesugar { .. }
419-
| hir::MatchSource::WhileLetDesugar => {
420-
// check which arm we're on.
421-
match arm_index {
422-
// The arm with the user-specified pattern.
423-
0 => {
424-
cx.tcx.lint_hir(
425-
lint::builtin::UNREACHABLE_PATTERNS,
426-
hir_pat.hir_id,
427-
pat.span,
428-
"unreachable pattern",
429-
);
430-
}
431-
// The arm with the wildcard pattern.
432-
1 => {
433-
let msg = match source {
434-
hir::MatchSource::IfLetDesugar { .. } => {
435-
"irrefutable if-let pattern"
436-
}
437-
hir::MatchSource::WhileLetDesugar => {
438-
"irrefutable while-let pattern"
439-
}
440-
_ => bug!(),
441-
};
442-
cx.tcx.lint_hir(
443-
lint::builtin::IRREFUTABLE_LET_PATTERNS,
444-
hir_pat.hir_id,
445-
pat.span,
446-
msg,
447-
);
448-
}
449-
_ => bug!(),
390+
for (arm_index, (pat, hir_pat, has_guard)) in arms.iter().enumerate() {
391+
let v = PatStack::from_pattern(pat);
392+
393+
match is_useful(cx, &seen, &v, LeaveOutWitness, hir_pat.hir_id) {
394+
NotUseful => {
395+
match source {
396+
hir::MatchSource::IfDesugar { .. } | hir::MatchSource::WhileDesugar => bug!(),
397+
398+
hir::MatchSource::IfLetDesugar { .. } | hir::MatchSource::WhileLetDesugar => {
399+
// check which arm we're on.
400+
match arm_index {
401+
// The arm with the user-specified pattern.
402+
0 => {
403+
cx.tcx.lint_hir(
404+
lint::builtin::UNREACHABLE_PATTERNS,
405+
hir_pat.hir_id,
406+
pat.span,
407+
"unreachable pattern",
408+
);
450409
}
451-
}
452-
453-
hir::MatchSource::ForLoopDesugar | hir::MatchSource::Normal => {
454-
let mut err = cx.tcx.struct_span_lint_hir(
455-
lint::builtin::UNREACHABLE_PATTERNS,
456-
hir_pat.hir_id,
457-
pat.span,
458-
"unreachable pattern",
459-
);
460-
// if we had a catchall pattern, hint at that
461-
if let Some(catchall) = catchall {
462-
err.span_label(pat.span, "unreachable pattern");
463-
err.span_label(catchall, "matches any value");
410+
// The arm with the wildcard pattern.
411+
1 => {
412+
let msg = match source {
413+
hir::MatchSource::IfLetDesugar { .. } => {
414+
"irrefutable if-let pattern"
415+
}
416+
hir::MatchSource::WhileLetDesugar => {
417+
"irrefutable while-let pattern"
418+
}
419+
_ => bug!(),
420+
};
421+
cx.tcx.lint_hir(
422+
lint::builtin::IRREFUTABLE_LET_PATTERNS,
423+
hir_pat.hir_id,
424+
pat.span,
425+
msg,
426+
);
464427
}
465-
err.emit();
428+
_ => bug!(),
466429
}
467-
468-
// Unreachable patterns in try and await expressions occur when one of
469-
// the arms are an uninhabited type. Which is OK.
470-
hir::MatchSource::AwaitDesugar | hir::MatchSource::TryDesugar => {}
471430
}
472-
}
473-
Useful(unreachable_subpatterns) => {
474-
for pat in unreachable_subpatterns {
475-
cx.tcx.lint_hir(
431+
432+
hir::MatchSource::ForLoopDesugar | hir::MatchSource::Normal => {
433+
let mut err = cx.tcx.struct_span_lint_hir(
476434
lint::builtin::UNREACHABLE_PATTERNS,
477435
hir_pat.hir_id,
478436
pat.span,
479437
"unreachable pattern",
480438
);
439+
// if we had a catchall pattern, hint at that
440+
if let Some(catchall) = catchall {
441+
err.span_label(pat.span, "unreachable pattern");
442+
err.span_label(catchall, "matches any value");
443+
}
444+
err.emit();
481445
}
446+
447+
// Unreachable patterns in try and await expressions occur when one of
448+
// the arms are an uninhabited type. Which is OK.
449+
hir::MatchSource::AwaitDesugar | hir::MatchSource::TryDesugar => {}
482450
}
483-
UsefulWithWitness(_) => bug!(),
484451
}
485-
if guard.is_none() {
486-
seen.push(v);
487-
if catchall.is_none() && pat_is_catchall(hir_pat) {
488-
catchall = Some(pat.span);
452+
Useful(unreachable_subpatterns) => {
453+
for pat in unreachable_subpatterns {
454+
cx.tcx.lint_hir(
455+
lint::builtin::UNREACHABLE_PATTERNS,
456+
hir_pat.hir_id,
457+
pat.span,
458+
"unreachable pattern",
459+
);
489460
}
490461
}
462+
UsefulWithWitness(_) => bug!(),
463+
}
464+
if !has_guard {
465+
seen.push(v);
466+
if catchall.is_none() && pat_is_catchall(hir_pat) {
467+
catchall = Some(pat.span);
468+
}
491469
}
492470
}
493471
seen

src/test/ui/pattern/usefulness/top-level-alternation.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ fn main() {
4646
match Some(0u8) {
4747
Some(_) => {}
4848
None => {}
49-
None //~ ERROR unreachable pattern
50-
| Some(_) => {} //~ ERROR unreachable pattern
49+
None | Some(_) => {} //~ ERROR unreachable pattern
5150
}
5251
match 0u8 {
5352
1 | 2 => {},

src/test/ui/pattern/usefulness/top-level-alternation.stderr

+4-10
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,14 @@ LL | None => {}
5555
error: unreachable pattern
5656
--> $DIR/top-level-alternation.rs:49:9
5757
|
58-
LL | None
59-
| ^^^^
60-
61-
error: unreachable pattern
62-
--> $DIR/top-level-alternation.rs:50:15
63-
|
64-
LL | | Some(_) => {}
65-
| ^^^^^^^
58+
LL | None | Some(_) => {}
59+
| ^^^^^^^^^^^^^^
6660

6761
error: unreachable pattern
68-
--> $DIR/top-level-alternation.rs:54:9
62+
--> $DIR/top-level-alternation.rs:53:9
6963
|
7064
LL | 1..=2 => {},
7165
| ^^^^^
7266

73-
error: aborting due to 11 previous errors
67+
error: aborting due to 10 previous errors
7468

0 commit comments

Comments
 (0)