Rollup merge of #120420 - lnicola:rm-pattern-analysis-derivative, r=Nilstrieb
Stop using derivative in rustc_pattern_analysis CC #109302, https://github.com/rust-lang/rust-analyzer/pull/16420#discussion_r1464357157 r? ````@Nadrieril````
This commit is contained in:
commit
5de94a3c80
@ -4342,7 +4342,6 @@ dependencies = [
|
|||||||
name = "rustc_pattern_analysis"
|
name = "rustc_pattern_analysis"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"derivative",
|
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"rustc_apfloat",
|
"rustc_apfloat",
|
||||||
"rustc_arena",
|
"rustc_arena",
|
||||||
|
@ -5,7 +5,6 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# tidy-alphabetical-start
|
# tidy-alphabetical-start
|
||||||
derivative = "2.2.0"
|
|
||||||
rustc-hash = "1.1.0"
|
rustc-hash = "1.1.0"
|
||||||
rustc_apfloat = "0.2.0"
|
rustc_apfloat = "0.2.0"
|
||||||
rustc_arena = { path = "../rustc_arena", optional = true }
|
rustc_arena = { path = "../rustc_arena", optional = true }
|
||||||
|
@ -151,6 +151,7 @@
|
|||||||
use std::cmp::{self, max, min, Ordering};
|
use std::cmp::{self, max, min, Ordering};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
@ -648,8 +649,6 @@ impl OpaqueId {
|
|||||||
/// `specialize_constructor` returns the list of fields corresponding to a pattern, given a
|
/// `specialize_constructor` returns the list of fields corresponding to a pattern, given a
|
||||||
/// constructor. `Constructor::apply` reconstructs the pattern from a pair of `Constructor` and
|
/// constructor. `Constructor::apply` reconstructs the pattern from a pair of `Constructor` and
|
||||||
/// `Fields`.
|
/// `Fields`.
|
||||||
#[derive(derivative::Derivative)]
|
|
||||||
#[derivative(Debug(bound = ""), Clone(bound = ""), PartialEq(bound = ""))]
|
|
||||||
pub enum Constructor<Cx: TypeCx> {
|
pub enum Constructor<Cx: TypeCx> {
|
||||||
/// Tuples and structs.
|
/// Tuples and structs.
|
||||||
Struct,
|
Struct,
|
||||||
@ -692,6 +691,101 @@ pub enum Constructor<Cx: TypeCx> {
|
|||||||
Missing,
|
Missing,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Cx: TypeCx> Clone for Constructor<Cx> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
Constructor::Struct => Constructor::Struct,
|
||||||
|
Constructor::Variant(idx) => Constructor::Variant(idx.clone()),
|
||||||
|
Constructor::Ref => Constructor::Ref,
|
||||||
|
Constructor::Slice(slice) => Constructor::Slice(slice.clone()),
|
||||||
|
Constructor::UnionField => Constructor::UnionField,
|
||||||
|
Constructor::Bool(b) => Constructor::Bool(b.clone()),
|
||||||
|
Constructor::IntRange(range) => Constructor::IntRange(range.clone()),
|
||||||
|
Constructor::F32Range(lo, hi, end) => {
|
||||||
|
Constructor::F32Range(lo.clone(), hi.clone(), end.clone())
|
||||||
|
}
|
||||||
|
Constructor::F64Range(lo, hi, end) => {
|
||||||
|
Constructor::F64Range(lo.clone(), hi.clone(), end.clone())
|
||||||
|
}
|
||||||
|
Constructor::Str(value) => Constructor::Str(value.clone()),
|
||||||
|
Constructor::Opaque(inner) => Constructor::Opaque(inner.clone()),
|
||||||
|
Constructor::Or => Constructor::Or,
|
||||||
|
Constructor::Wildcard => Constructor::Wildcard,
|
||||||
|
Constructor::NonExhaustive => Constructor::NonExhaustive,
|
||||||
|
Constructor::Hidden => Constructor::Hidden,
|
||||||
|
Constructor::Missing => Constructor::Missing,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Cx: TypeCx> fmt::Debug for Constructor<Cx> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Constructor::Struct => f.debug_tuple("Struct").finish(),
|
||||||
|
Constructor::Variant(idx) => f.debug_tuple("Variant").field(idx).finish(),
|
||||||
|
Constructor::Ref => f.debug_tuple("Ref").finish(),
|
||||||
|
Constructor::Slice(slice) => f.debug_tuple("Slice").field(slice).finish(),
|
||||||
|
Constructor::UnionField => f.debug_tuple("UnionField").finish(),
|
||||||
|
Constructor::Bool(b) => f.debug_tuple("Bool").field(b).finish(),
|
||||||
|
Constructor::IntRange(range) => f.debug_tuple("IntRange").field(range).finish(),
|
||||||
|
Constructor::F32Range(lo, hi, end) => {
|
||||||
|
f.debug_tuple("F32Range").field(lo).field(hi).field(end).finish()
|
||||||
|
}
|
||||||
|
Constructor::F64Range(lo, hi, end) => {
|
||||||
|
f.debug_tuple("F64Range").field(lo).field(hi).field(end).finish()
|
||||||
|
}
|
||||||
|
Constructor::Str(value) => f.debug_tuple("Str").field(value).finish(),
|
||||||
|
Constructor::Opaque(inner) => f.debug_tuple("Opaque").field(inner).finish(),
|
||||||
|
Constructor::Or => f.debug_tuple("Or").finish(),
|
||||||
|
Constructor::Wildcard => f.debug_tuple("Wildcard").finish(),
|
||||||
|
Constructor::NonExhaustive => f.debug_tuple("NonExhaustive").finish(),
|
||||||
|
Constructor::Hidden => f.debug_tuple("Hidden").finish(),
|
||||||
|
Constructor::Missing => f.debug_tuple("Missing").finish(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Cx: TypeCx> PartialEq for Constructor<Cx> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
(mem::discriminant(self) == mem::discriminant(other))
|
||||||
|
&& match (self, other) {
|
||||||
|
(Constructor::Struct, Constructor::Struct) => true,
|
||||||
|
(Constructor::Variant(self_variant), Constructor::Variant(other_variant)) => {
|
||||||
|
self_variant == other_variant
|
||||||
|
}
|
||||||
|
(Constructor::Ref, Constructor::Ref) => true,
|
||||||
|
(Constructor::Slice(self_slice), Constructor::Slice(other_slice)) => {
|
||||||
|
self_slice == other_slice
|
||||||
|
}
|
||||||
|
(Constructor::UnionField, Constructor::UnionField) => true,
|
||||||
|
(Constructor::Bool(self_b), Constructor::Bool(other_b)) => self_b == other_b,
|
||||||
|
(Constructor::IntRange(self_range), Constructor::IntRange(other_range)) => {
|
||||||
|
self_range == other_range
|
||||||
|
}
|
||||||
|
(
|
||||||
|
Constructor::F32Range(self_lo, self_hi, self_end),
|
||||||
|
Constructor::F32Range(other_lo, other_hi, other_end),
|
||||||
|
) => self_lo == other_lo && self_hi == other_hi && self_end == other_end,
|
||||||
|
(
|
||||||
|
Constructor::F64Range(self_lo, self_hi, self_end),
|
||||||
|
Constructor::F64Range(other_lo, other_hi, other_end),
|
||||||
|
) => self_lo == other_lo && self_hi == other_hi && self_end == other_end,
|
||||||
|
(Constructor::Str(self_value), Constructor::Str(other_value)) => {
|
||||||
|
self_value == other_value
|
||||||
|
}
|
||||||
|
(Constructor::Opaque(self_inner), Constructor::Opaque(other_inner)) => {
|
||||||
|
self_inner == other_inner
|
||||||
|
}
|
||||||
|
(Constructor::Or, Constructor::Or) => true,
|
||||||
|
(Constructor::Wildcard, Constructor::Wildcard) => true,
|
||||||
|
(Constructor::NonExhaustive, Constructor::NonExhaustive) => true,
|
||||||
|
(Constructor::Hidden, Constructor::Hidden) => true,
|
||||||
|
(Constructor::Missing, Constructor::Missing) => true,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<Cx: TypeCx> Constructor<Cx> {
|
impl<Cx: TypeCx> Constructor<Cx> {
|
||||||
pub(crate) fn is_non_exhaustive(&self) -> bool {
|
pub(crate) fn is_non_exhaustive(&self) -> bool {
|
||||||
matches!(self, NonExhaustive)
|
matches!(self, NonExhaustive)
|
||||||
|
@ -136,23 +136,35 @@ pub trait TypeCx: Sized + fmt::Debug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Context that provides information global to a match.
|
/// Context that provides information global to a match.
|
||||||
#[derive(derivative::Derivative)]
|
|
||||||
#[derivative(Clone(bound = ""), Copy(bound = ""))]
|
|
||||||
pub struct MatchCtxt<'a, Cx: TypeCx> {
|
pub struct MatchCtxt<'a, Cx: TypeCx> {
|
||||||
/// The context for type information.
|
/// The context for type information.
|
||||||
pub tycx: &'a Cx,
|
pub tycx: &'a Cx,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, Cx: TypeCx> Clone for MatchCtxt<'a, Cx> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self { tycx: self.tycx }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Cx: TypeCx> Copy for MatchCtxt<'a, Cx> {}
|
||||||
|
|
||||||
/// The arm of a match expression.
|
/// The arm of a match expression.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[derive(derivative::Derivative)]
|
|
||||||
#[derivative(Clone(bound = ""), Copy(bound = ""))]
|
|
||||||
pub struct MatchArm<'p, Cx: TypeCx> {
|
pub struct MatchArm<'p, Cx: TypeCx> {
|
||||||
pub pat: &'p DeconstructedPat<'p, Cx>,
|
pub pat: &'p DeconstructedPat<'p, Cx>,
|
||||||
pub has_guard: bool,
|
pub has_guard: bool,
|
||||||
pub arm_data: Cx::ArmData,
|
pub arm_data: Cx::ArmData,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'p, Cx: TypeCx> Clone for MatchArm<'p, Cx> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self { pat: self.pat, has_guard: self.has_guard, arm_data: self.arm_data }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'p, Cx: TypeCx> Copy for MatchArm<'p, Cx> {}
|
||||||
|
|
||||||
/// The entrypoint for this crate. Computes whether a match is exhaustive and which of its arms are
|
/// The entrypoint for this crate. Computes whether a match is exhaustive and which of its arms are
|
||||||
/// useful, and runs some lints.
|
/// useful, and runs some lints.
|
||||||
#[cfg(feature = "rustc")]
|
#[cfg(feature = "rustc")]
|
||||||
|
@ -218,8 +218,6 @@ impl<'p, Cx: TypeCx> fmt::Debug for DeconstructedPat<'p, Cx> {
|
|||||||
/// algorithm. Do not use `Wild` to represent a wildcard pattern comping from user input.
|
/// algorithm. Do not use `Wild` to represent a wildcard pattern comping from user input.
|
||||||
///
|
///
|
||||||
/// This is morally `Option<&'p DeconstructedPat>` where `None` is interpreted as a wildcard.
|
/// This is morally `Option<&'p DeconstructedPat>` where `None` is interpreted as a wildcard.
|
||||||
#[derive(derivative::Derivative)]
|
|
||||||
#[derivative(Clone(bound = ""), Copy(bound = ""))]
|
|
||||||
pub(crate) enum PatOrWild<'p, Cx: TypeCx> {
|
pub(crate) enum PatOrWild<'p, Cx: TypeCx> {
|
||||||
/// A non-user-provided wildcard, created during specialization.
|
/// A non-user-provided wildcard, created during specialization.
|
||||||
Wild,
|
Wild,
|
||||||
@ -227,6 +225,17 @@ pub(crate) enum PatOrWild<'p, Cx: TypeCx> {
|
|||||||
Pat(&'p DeconstructedPat<'p, Cx>),
|
Pat(&'p DeconstructedPat<'p, Cx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'p, Cx: TypeCx> Clone for PatOrWild<'p, Cx> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
PatOrWild::Wild => PatOrWild::Wild,
|
||||||
|
PatOrWild::Pat(pat) => PatOrWild::Pat(pat),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'p, Cx: TypeCx> Copy for PatOrWild<'p, Cx> {}
|
||||||
|
|
||||||
impl<'p, Cx: TypeCx> PatOrWild<'p, Cx> {
|
impl<'p, Cx: TypeCx> PatOrWild<'p, Cx> {
|
||||||
pub(crate) fn as_pat(&self) -> Option<&'p DeconstructedPat<'p, Cx>> {
|
pub(crate) fn as_pat(&self) -> Option<&'p DeconstructedPat<'p, Cx>> {
|
||||||
match self {
|
match self {
|
||||||
@ -289,14 +298,28 @@ impl<'p, Cx: TypeCx> fmt::Debug for PatOrWild<'p, Cx> {
|
|||||||
|
|
||||||
/// Same idea as `DeconstructedPat`, except this is a fictitious pattern built up for diagnostics
|
/// Same idea as `DeconstructedPat`, except this is a fictitious pattern built up for diagnostics
|
||||||
/// purposes. As such they don't use interning and can be cloned.
|
/// purposes. As such they don't use interning and can be cloned.
|
||||||
#[derive(derivative::Derivative)]
|
|
||||||
#[derivative(Debug(bound = ""), Clone(bound = ""))]
|
|
||||||
pub struct WitnessPat<Cx: TypeCx> {
|
pub struct WitnessPat<Cx: TypeCx> {
|
||||||
ctor: Constructor<Cx>,
|
ctor: Constructor<Cx>,
|
||||||
pub(crate) fields: Vec<WitnessPat<Cx>>,
|
pub(crate) fields: Vec<WitnessPat<Cx>>,
|
||||||
ty: Cx::Ty,
|
ty: Cx::Ty,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Cx: TypeCx> Clone for WitnessPat<Cx> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self { ctor: self.ctor.clone(), fields: self.fields.clone(), ty: self.ty.clone() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Cx: TypeCx> fmt::Debug for WitnessPat<Cx> {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt.debug_struct("WitnessPat")
|
||||||
|
.field("ctor", &self.ctor)
|
||||||
|
.field("fields", &self.fields)
|
||||||
|
.field("ty", &self.ty)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<Cx: TypeCx> WitnessPat<Cx> {
|
impl<Cx: TypeCx> WitnessPat<Cx> {
|
||||||
pub(crate) fn new(ctor: Constructor<Cx>, fields: Vec<Self>, ty: Cx::Ty) -> Self {
|
pub(crate) fn new(ctor: Constructor<Cx>, fields: Vec<Self>, ty: Cx::Ty) -> Self {
|
||||||
Self { ctor, fields, ty }
|
Self { ctor, fields, ty }
|
||||||
|
@ -46,11 +46,15 @@ pub type WitnessPat<'p, 'tcx> = crate::pat::WitnessPat<RustcMatchCheckCtxt<'p, '
|
|||||||
///
|
///
|
||||||
/// Use `.inner()` or deref to get to the `Ty<'tcx>`.
|
/// Use `.inner()` or deref to get to the `Ty<'tcx>`.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(derivative::Derivative)]
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
#[derivative(Debug = "transparent")]
|
|
||||||
pub struct RevealedTy<'tcx>(Ty<'tcx>);
|
pub struct RevealedTy<'tcx>(Ty<'tcx>);
|
||||||
|
|
||||||
|
impl<'tcx> fmt::Debug for RevealedTy<'tcx> {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.0.fmt(fmt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> std::ops::Deref for RevealedTy<'tcx> {
|
impl<'tcx> std::ops::Deref for RevealedTy<'tcx> {
|
||||||
type Target = Ty<'tcx>;
|
type Target = Ty<'tcx>;
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
|
@ -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.
|
/// 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> {
|
pub(crate) struct PlaceCtxt<'a, Cx: TypeCx> {
|
||||||
#[derivative(Debug = "ignore")]
|
|
||||||
pub(crate) mcx: MatchCtxt<'a, Cx>,
|
pub(crate) mcx: MatchCtxt<'a, Cx>,
|
||||||
/// Type of the place under investigation.
|
/// Type of the place under investigation.
|
||||||
#[derivative(Clone(clone_with = "Clone::clone"))] // See rust-derivative#90
|
|
||||||
pub(crate) ty: &'a Cx::Ty,
|
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> {
|
impl<'a, Cx: TypeCx> PlaceCtxt<'a, Cx> {
|
||||||
/// A `PlaceCtxt` when code other than `is_useful` needs one.
|
/// A `PlaceCtxt` when code other than `is_useful` needs one.
|
||||||
#[cfg_attr(not(feature = "rustc"), allow(dead_code))]
|
#[cfg_attr(not(feature = "rustc"), allow(dead_code))]
|
||||||
@ -813,8 +823,6 @@ impl fmt::Display for ValidityConstraint {
|
|||||||
// The three lifetimes are:
|
// The three lifetimes are:
|
||||||
// - 'p coming from the input
|
// - 'p coming from the input
|
||||||
// - Cx global compilation context
|
// - Cx global compilation context
|
||||||
#[derive(derivative::Derivative)]
|
|
||||||
#[derivative(Clone(bound = ""))]
|
|
||||||
struct PatStack<'p, Cx: TypeCx> {
|
struct PatStack<'p, Cx: TypeCx> {
|
||||||
// Rows of len 1 are very common, which is why `SmallVec[_; 2]` works well.
|
// Rows of len 1 are very common, which is why `SmallVec[_; 2]` works well.
|
||||||
pats: SmallVec<[PatOrWild<'p, Cx>; 2]>,
|
pats: SmallVec<[PatOrWild<'p, Cx>; 2]>,
|
||||||
@ -824,6 +832,12 @@ struct PatStack<'p, Cx: TypeCx> {
|
|||||||
relevant: bool,
|
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> {
|
impl<'p, Cx: TypeCx> PatStack<'p, Cx> {
|
||||||
fn from_pattern(pat: &'p DeconstructedPat<'p, Cx>) -> Self {
|
fn from_pattern(pat: &'p DeconstructedPat<'p, Cx>) -> Self {
|
||||||
PatStack { pats: smallvec![PatOrWild::Pat(pat)], relevant: true }
|
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.
|
/// The final `Pair(Some(_), true)` is then the resulting witness.
|
||||||
///
|
///
|
||||||
/// See the top of the file for more detailed explanations and examples.
|
/// 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>>);
|
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> {
|
impl<Cx: TypeCx> WitnessStack<Cx> {
|
||||||
/// Asserts that the witness contains a single pattern, and returns it.
|
/// Asserts that the witness contains a single pattern, and returns it.
|
||||||
fn single_pattern(self) -> WitnessPat<Cx> {
|
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
|
/// 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.
|
/// 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>>);
|
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> {
|
impl<Cx: TypeCx> WitnessMatrix<Cx> {
|
||||||
/// New matrix with no witnesses.
|
/// New matrix with no witnesses.
|
||||||
fn empty() -> Self {
|
fn empty() -> Self {
|
||||||
WitnessMatrix(vec![])
|
WitnessMatrix(Vec::new())
|
||||||
}
|
}
|
||||||
/// New matrix with one `()` witness, i.e. with no columns.
|
/// New matrix with one `()` witness, i.e. with no columns.
|
||||||
fn unit_witness() -> Self {
|
fn unit_witness() -> Self {
|
||||||
WitnessMatrix(vec![WitnessStack(vec![])])
|
WitnessMatrix(vec![WitnessStack(Vec::new())])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether this has any witnesses.
|
/// Whether this has any witnesses.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user