Skip to content

Commit 3dfd0fd

Browse files
committed
Report arm intersections
1 parent 3c85e56 commit 3dfd0fd

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

compiler/rustc_pattern_analysis/src/usefulness.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,7 @@ struct MatrixRow<'p, Cx: PatCx> {
10421042
is_under_guard: bool,
10431043
/// When we specialize, we remember which row of the original matrix produced a given row of the
10441044
/// specialized matrix. When we unspecialize, we use this to propagate usefulness back up the
1045-
/// callstack.
1045+
/// callstack. On creation, this stores the index of the original match arm.
10461046
parent_row: usize,
10471047
/// False when the matrix is just built. This is set to `true` by
10481048
/// [`compute_exhaustiveness_and_usefulness`] if the arm is found to be useful.
@@ -1163,10 +1163,10 @@ impl<'p, Cx: PatCx> Matrix<'p, Cx> {
11631163
place_info: smallvec![place_info],
11641164
wildcard_row_is_relevant: true,
11651165
};
1166-
for (row_id, arm) in arms.iter().enumerate() {
1166+
for (arm_id, arm) in arms.iter().enumerate() {
11671167
let v = MatrixRow {
11681168
pats: PatStack::from_pattern(arm.pat),
1169-
parent_row: row_id, // dummy, we don't read it
1169+
parent_row: arm_id,
11701170
is_under_guard: arm.has_guard,
11711171
useful: false,
11721172
intersects: BitSet::new_empty(0), // Initialized in `Matrix::expand_and_push`.
@@ -1738,6 +1738,9 @@ pub struct UsefulnessReport<'p, Cx: PatCx> {
17381738
/// If the match is exhaustive, this is empty. If not, this contains witnesses for the lack of
17391739
/// exhaustiveness.
17401740
pub non_exhaustiveness_witnesses: Vec<WitnessPat<Cx>>,
1741+
/// For each arm, a set of indices of arms above it that have non-empty intersection, i.e. there
1742+
/// is a value matched by both arms. This may miss real intersections.
1743+
pub arm_intersections: Vec<BitSet<usize>>,
17411744
}
17421745

17431746
/// Computes whether a match is exhaustive and which of its arms are useful.
@@ -1769,5 +1772,19 @@ pub fn compute_match_usefulness<'p, Cx: PatCx>(
17691772
})
17701773
.collect();
17711774

1772-
Ok(UsefulnessReport { arm_usefulness, non_exhaustiveness_witnesses })
1775+
let mut arm_intersections: Vec<_> =
1776+
arms.iter().enumerate().map(|(i, _)| BitSet::new_empty(i)).collect();
1777+
for row in matrix.rows() {
1778+
let arm_id = row.parent_row;
1779+
for intersection in row.intersects.iter() {
1780+
// Convert the matrix row ids into arm ids (they can differ because we expand or-patterns).
1781+
let arm_intersection = matrix.rows[intersection].parent_row;
1782+
// Note: self-intersection can happen with or-patterns.
1783+
if arm_intersection != arm_id {
1784+
arm_intersections[arm_id].insert(arm_intersection);
1785+
}
1786+
}
1787+
}
1788+
1789+
Ok(UsefulnessReport { arm_usefulness, non_exhaustiveness_witnesses, arm_intersections })
17731790
}

0 commit comments

Comments
 (0)