Skip to content

Commit 4b2c6e8

Browse files
committed
Track is_top_level via PlaceInfo
1 parent 1875146 commit 4b2c6e8

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

compiler/rustc_pattern_analysis/src/usefulness.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,8 @@ struct PlaceInfo<Cx: TypeCx> {
828828
ty: Cx::Ty,
829829
/// Whether the place is known to contain valid data.
830830
validity: ValidityConstraint,
831+
/// Whether the place is the scrutinee itself or a subplace of it.
832+
is_scrutinee: bool,
831833
}
832834

833835
impl<Cx: TypeCx> PlaceInfo<Cx> {
@@ -838,13 +840,17 @@ impl<Cx: TypeCx> PlaceInfo<Cx> {
838840
) -> impl Iterator<Item = Self> + ExactSizeIterator + Captures<'a> {
839841
let ctor_sub_tys = cx.ctor_sub_tys(ctor, &self.ty);
840842
let ctor_sub_validity = self.validity.specialize(ctor);
841-
ctor_sub_tys.map(move |ty| PlaceInfo { ty, validity: ctor_sub_validity })
843+
ctor_sub_tys.map(move |ty| PlaceInfo {
844+
ty,
845+
validity: ctor_sub_validity,
846+
is_scrutinee: false,
847+
})
842848
}
843849
}
844850

845851
impl<Cx: TypeCx> Clone for PlaceInfo<Cx> {
846852
fn clone(&self) -> Self {
847-
Self { ty: self.ty.clone(), validity: self.validity }
853+
Self { ty: self.ty.clone(), validity: self.validity, is_scrutinee: self.is_scrutinee }
848854
}
849855
}
850856

@@ -1051,7 +1057,7 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
10511057
scrut_ty: Cx::Ty,
10521058
scrut_validity: ValidityConstraint,
10531059
) -> Self {
1054-
let place_info = PlaceInfo { ty: scrut_ty, validity: scrut_validity };
1060+
let place_info = PlaceInfo { ty: scrut_ty, validity: scrut_validity, is_scrutinee: true };
10551061
let mut matrix = Matrix {
10561062
rows: Vec::with_capacity(arms.len()),
10571063
place_info: smallvec![place_info],
@@ -1456,11 +1462,10 @@ fn collect_overlapping_range_endpoints<'p, Cx: TypeCx>(
14561462
/// - unspecialization, where we lift the results from the previous step into results for this step
14571463
/// (using `apply_constructor` and by updating `row.useful` for each parent row).
14581464
/// This is all explained at the top of the file.
1459-
#[instrument(level = "debug", skip(mcx, is_top_level), ret)]
1465+
#[instrument(level = "debug", skip(mcx), ret)]
14601466
fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
14611467
mcx: UsefulnessCtxt<'a, Cx>,
14621468
matrix: &mut Matrix<'p, Cx>,
1463-
is_top_level: bool,
14641469
) -> Result<WitnessMatrix<Cx>, Cx::Error> {
14651470
debug_assert!(matrix.rows().all(|r| r.len() == matrix.column_count()));
14661471

@@ -1498,7 +1503,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
14981503

14991504
// We treat match scrutinees of type `!` or `EmptyEnum` differently.
15001505
let is_toplevel_exception =
1501-
is_top_level && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
1506+
place.is_scrutinee && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
15021507
// Whether empty patterns are counted as useful or not. We only warn an empty arm unreachable if
15031508
// it is guaranteed unreachable by the opsem (i.e. if the place is `known_valid`).
15041509
let empty_arms_are_unreachable = place.validity.is_known_valid()
@@ -1527,7 +1532,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
15271532

15281533
// Decide what constructors to report.
15291534
let is_integers = matches!(ctors_for_ty, ConstructorSet::Integers { .. });
1530-
let always_report_all = is_top_level && !is_integers;
1535+
let always_report_all = place.is_scrutinee && !is_integers;
15311536
// Whether we should report "Enum::A and Enum::C are missing" or "_ is missing".
15321537
let report_individual_missing_ctors = always_report_all || !all_missing;
15331538
// Which constructors are considered missing. We ensure that `!missing_ctors.is_empty() =>
@@ -1548,7 +1553,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
15481553
let ctor_is_relevant = matches!(ctor, Constructor::Missing) || missing_ctors.is_empty();
15491554
let mut spec_matrix = matrix.specialize_constructor(pcx, &ctor, ctor_is_relevant)?;
15501555
let mut witnesses = ensure_sufficient_stack(|| {
1551-
compute_exhaustiveness_and_usefulness(mcx, &mut spec_matrix, false)
1556+
compute_exhaustiveness_and_usefulness(mcx, &mut spec_matrix)
15521557
})?;
15531558

15541559
// Transform witnesses for `spec_matrix` into witnesses for `matrix`.
@@ -1623,8 +1628,7 @@ pub fn compute_match_usefulness<'p, Cx: TypeCx>(
16231628
) -> Result<UsefulnessReport<'p, Cx>, Cx::Error> {
16241629
let cx = UsefulnessCtxt { tycx };
16251630
let mut matrix = Matrix::new(arms, scrut_ty, scrut_validity);
1626-
let non_exhaustiveness_witnesses =
1627-
compute_exhaustiveness_and_usefulness(cx, &mut matrix, true)?;
1631+
let non_exhaustiveness_witnesses = compute_exhaustiveness_and_usefulness(cx, &mut matrix)?;
16281632

16291633
let non_exhaustiveness_witnesses: Vec<_> = non_exhaustiveness_witnesses.single_column();
16301634
let arm_usefulness: Vec<_> = arms

0 commit comments

Comments
 (0)