Skip to content

Commit

Permalink
Auto merge of rust-lang#80632 - Nadrieril:fix-80501, r=varkor
Browse files Browse the repository at this point in the history
Identify unreachable subpatterns more reliably

In rust-lang#80104 I used `Span`s to identify unreachable sub-patterns in the presence of or-patterns during exhaustiveness checking. In rust-lang#80501 it was revealed that `Span`s are complicated and that this was not a good idea.
Instead, this PR identifies subpatterns logically: as a path in the tree of subpatterns of a given pattern. I made a struct that captures a set of such subpatterns. This is a bit complex, but thankfully self-contained; the rest of the code does not need to know anything about it.
Fixes rust-lang#80501. I think I managed to keep the perf neutral.

r? `@varkor`
  • Loading branch information
bors committed Feb 7, 2021
2 parents 5a5f3a9 + ae6fcab commit 36ecbc9
Show file tree
Hide file tree
Showing 6 changed files with 472 additions and 223 deletions.
14 changes: 7 additions & 7 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::usefulness::Usefulness::*;
use super::usefulness::{
compute_match_usefulness, expand_pattern, MatchArm, MatchCheckCtxt, UsefulnessReport,
compute_match_usefulness, expand_pattern, MatchArm, MatchCheckCtxt, Reachability,
UsefulnessReport,
};
use super::{PatCtxt, PatKind, PatternError};

Expand Down Expand Up @@ -398,10 +398,11 @@ fn report_arm_reachability<'p, 'tcx>(
report: &UsefulnessReport<'p, 'tcx>,
source: hir::MatchSource,
) {
use Reachability::*;
let mut catchall = None;
for (arm_index, (arm, is_useful)) in report.arm_usefulness.iter().enumerate() {
match is_useful {
NotUseful => {
Unreachable => {
match source {
hir::MatchSource::WhileDesugar => bug!(),

Expand Down Expand Up @@ -430,17 +431,16 @@ fn report_arm_reachability<'p, 'tcx>(
hir::MatchSource::AwaitDesugar | hir::MatchSource::TryDesugar => {}
}
}
Useful(unreachables) if unreachables.is_empty() => {}
Reachable(unreachables) if unreachables.is_empty() => {}
// The arm is reachable, but contains unreachable subpatterns (from or-patterns).
Useful(unreachables) => {
let mut unreachables: Vec<_> = unreachables.iter().collect();
Reachable(unreachables) => {
let mut unreachables = unreachables.clone();
// Emit lints in the order in which they occur in the file.
unreachables.sort_unstable();
for span in unreachables {
unreachable_pattern(cx.tcx, span, arm.hir_id, None);
}
}
UsefulWithWitness(_) => bug!(),
}
if !arm.has_guard && catchall.is_none() && pat_is_catchall(arm.pat) {
catchall = Some(arm.pat.span);
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,8 +723,6 @@ impl<'tcx> Constructor<'tcx> {
where
'tcx: 'a,
{
debug!("Constructor::split({:#?})", self);

match self {
Wildcard => {
let mut split_wildcard = SplitWildcard::new(pcx);
Expand Down
Loading

0 comments on commit 36ecbc9

Please sign in to comment.