diff --git a/compiler/rustc_pattern_analysis/src/pat.rs b/compiler/rustc_pattern_analysis/src/pat.rs index 2314da7149b..04a77faad74 100644 --- a/compiler/rustc_pattern_analysis/src/pat.rs +++ b/compiler/rustc_pattern_analysis/src/pat.rs @@ -1,6 +1,5 @@ //! As explained in [`crate::usefulness`], values and patterns are made from constructors applied to //! fields. This file defines types that represent patterns in this way. -use std::cell::Cell; use std::fmt; use smallvec::{smallvec, SmallVec}; @@ -11,11 +10,8 @@ use self::Constructor::*; /// Values and patterns can be represented as a constructor applied to some fields. This represents -/// a pattern in this form. -/// This also uses interior mutability to keep track of whether the pattern has been found reachable -/// during analysis. For this reason they cannot be cloned. -/// A `DeconstructedPat` will almost always come from user input; the only exception are some -/// `Wildcard`s introduced during specialization. +/// a pattern in this form. A `DeconstructedPat` will almost always come from user input; the only +/// exception are some `Wildcard`s introduced during pattern lowering. /// /// Note that the number of fields may not match the fields declared in the original struct/variant. /// This happens if a private or `non_exhaustive` field is uninhabited, because the code mustn't @@ -28,19 +24,11 @@ pub struct DeconstructedPat { /// Extra data to store in a pattern. `None` if the pattern is a wildcard that does not /// correspond to a user-supplied pattern. data: Option, - /// Whether removing this arm would change the behavior of the match expression. - pub(crate) useful: Cell, } impl DeconstructedPat { pub fn wildcard(ty: Cx::Ty) -> Self { - DeconstructedPat { - ctor: Wildcard, - fields: Vec::new(), - ty, - data: None, - useful: Cell::new(false), - } + DeconstructedPat { ctor: Wildcard, fields: Vec::new(), ty, data: None } } pub fn new( @@ -49,7 +37,7 @@ pub fn new( ty: Cx::Ty, data: Cx::PatData, ) -> Self { - DeconstructedPat { ctor, fields, ty, data: Some(data), useful: Cell::new(false) } + DeconstructedPat { ctor, fields, ty, data: Some(data) } } pub(crate) fn is_or_pat(&self) -> bool { @@ -107,12 +95,6 @@ pub(crate) fn specialize<'a>( } } - /// We keep track for each pattern if it was ever useful during the analysis. This is used with - /// `redundant_subpatterns` to report redundant subpatterns arising from or patterns. - pub(crate) fn set_useful(&self) { - self.useful.set(true) - } - /// Walk top-down and call `it` in each place where a pattern occurs /// starting with the root pattern `walk` is called on. If `it` returns /// false then we will descend no further but siblings will be processed. @@ -267,12 +249,6 @@ pub(crate) fn specialize( PatOrWild::Pat(pat) => pat.specialize(other_ctor, ctor_arity), } } - - pub(crate) fn set_useful(&self) { - if let PatOrWild::Pat(pat) = self { - pat.set_useful() - } - } } impl<'p, Cx: TypeCx> fmt::Debug for PatOrWild<'p, Cx> { diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs index 092e752e977..bcc734dc81c 100644 --- a/compiler/rustc_pattern_analysis/src/usefulness.rs +++ b/compiler/rustc_pattern_analysis/src/usefulness.rs @@ -466,13 +466,9 @@ //! first pattern of a row in the matrix is an or-pattern, we expand it by duplicating the rest of //! the row as necessary. This is handled automatically in [`Matrix`]. //! -//! This makes usefulness tracking subtle, because we also want to compute whether an alternative -//! of an or-pattern is redundant, e.g. in `Some(_) | Some(0)`. We track usefulness of each -//! subpattern by interior mutability in [`DeconstructedPat`] with `set_useful`/`is_useful`. -//! -//! It's unfortunate that we have to use interior mutability, but believe me (Nadrieril), I have -//! tried [other](https://github.com/rust-lang/rust/pull/80104) -//! [solutions](https://github.com/rust-lang/rust/pull/80632) and nothing is remotely as simple. +//! This makes usefulness tracking subtle, because we also want to compute whether an alternative of +//! an or-pattern is redundant, e.g. in `Some(_) | Some(0)`. We therefore track usefulness of each +//! subpattern of the match. //! //! //! @@ -1462,8 +1458,8 @@ fn collect_overlapping_range_endpoints<'p, Cx: TypeCx>( /// The core of the algorithm. /// /// This recursively computes witnesses of the non-exhaustiveness of `matrix` (if any). Also tracks -/// usefulness of each row in the matrix (in `row.useful`). We track usefulness of each -/// subpattern using interior mutability in `DeconstructedPat`. +/// usefulness of each row in the matrix (in `row.useful`). We track usefulness of each subpattern +/// in `mcx.useful_subpatterns`. /// /// The input `Matrix` and the output `WitnessMatrix` together match the type exhaustively. ///