Stop using derivative in rustc_pattern_analysis

This commit is contained in:
Laurențiu Nicola 2024-01-27 14:18:33 +02:00
parent 8b6a431b3d
commit f5c78955c8
7 changed files with 191 additions and 26 deletions

View file

@ -731,16 +731,26 @@ pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
}
/// Context that provides information local to a place under investigation.
#[derive(derivative::Derivative)]
#[derivative(Debug(bound = ""), Clone(bound = ""), Copy(bound = ""))]
pub(crate) struct PlaceCtxt<'a, Cx: TypeCx> {
#[derivative(Debug = "ignore")]
pub(crate) mcx: MatchCtxt<'a, Cx>,
/// Type of the place under investigation.
#[derivative(Clone(clone_with = "Clone::clone"))] // See rust-derivative#90
pub(crate) ty: &'a Cx::Ty,
}
impl<'a, Cx: TypeCx> Clone for PlaceCtxt<'a, Cx> {
fn clone(&self) -> Self {
Self { mcx: self.mcx, ty: self.ty }
}
}
impl<'a, Cx: TypeCx> Copy for PlaceCtxt<'a, Cx> {}
impl<'a, Cx: TypeCx> fmt::Debug for PlaceCtxt<'a, Cx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("PlaceCtxt").field("ty", self.ty).finish()
}
}
impl<'a, Cx: TypeCx> PlaceCtxt<'a, Cx> {
/// A `PlaceCtxt` when code other than `is_useful` needs one.
#[cfg_attr(not(feature = "rustc"), allow(dead_code))]
@ -813,8 +823,6 @@ impl fmt::Display for ValidityConstraint {
// The three lifetimes are:
// - 'p coming from the input
// - Cx global compilation context
#[derive(derivative::Derivative)]
#[derivative(Clone(bound = ""))]
struct PatStack<'p, Cx: TypeCx> {
// Rows of len 1 are very common, which is why `SmallVec[_; 2]` works well.
pats: SmallVec<[PatOrWild<'p, Cx>; 2]>,
@ -824,6 +832,12 @@ struct PatStack<'p, Cx: TypeCx> {
relevant: bool,
}
impl<'p, Cx: TypeCx> Clone for PatStack<'p, Cx> {
fn clone(&self) -> Self {
Self { pats: self.pats.clone(), relevant: self.relevant }
}
}
impl<'p, Cx: TypeCx> PatStack<'p, Cx> {
fn from_pattern(pat: &'p DeconstructedPat<'p, Cx>) -> Self {
PatStack { pats: smallvec![PatOrWild::Pat(pat)], relevant: true }
@ -1184,10 +1198,20 @@ impl<'p, Cx: TypeCx> fmt::Debug for Matrix<'p, Cx> {
/// The final `Pair(Some(_), true)` is then the resulting witness.
///
/// See the top of the file for more detailed explanations and examples.
#[derive(derivative::Derivative)]
#[derivative(Debug(bound = ""), Clone(bound = ""))]
struct WitnessStack<Cx: TypeCx>(Vec<WitnessPat<Cx>>);
impl<Cx: TypeCx> Clone for WitnessStack<Cx> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<Cx: TypeCx> fmt::Debug for WitnessStack<Cx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("WitnessStack").field(&self.0).finish()
}
}
impl<Cx: TypeCx> WitnessStack<Cx> {
/// Asserts that the witness contains a single pattern, and returns it.
fn single_pattern(self) -> WitnessPat<Cx> {
@ -1232,18 +1256,28 @@ impl<Cx: TypeCx> WitnessStack<Cx> {
///
/// Just as the `Matrix` starts with a single column, by the end of the algorithm, this has a single
/// column, which contains the patterns that are missing for the match to be exhaustive.
#[derive(derivative::Derivative)]
#[derivative(Debug(bound = ""), Clone(bound = ""))]
struct WitnessMatrix<Cx: TypeCx>(Vec<WitnessStack<Cx>>);
impl<Cx: TypeCx> Clone for WitnessMatrix<Cx> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<Cx: TypeCx> fmt::Debug for WitnessMatrix<Cx> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_tuple("WitnessMatrix").field(&self.0).finish()
}
}
impl<Cx: TypeCx> WitnessMatrix<Cx> {
/// New matrix with no witnesses.
fn empty() -> Self {
WitnessMatrix(vec![])
WitnessMatrix(Vec::new())
}
/// New matrix with one `()` witness, i.e. with no columns.
fn unit_witness() -> Self {
WitnessMatrix(vec![WitnessStack(vec![])])
WitnessMatrix(vec![WitnessStack(Vec::new())])
}
/// Whether this has any witnesses.