Add some tests

This commit is contained in:
Nadrieril 2024-07-21 14:37:10 +02:00
parent bab8ede761
commit c4d6a4a7e4
3 changed files with 74 additions and 4 deletions

View File

@ -25,7 +25,7 @@ pub fn init_tracing() {
/// A simple set of types.
#[allow(dead_code)]
#[derive(Debug, Copy, Clone)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Ty {
/// Booleans
Bool,
@ -33,6 +33,8 @@ pub enum Ty {
U8,
/// Tuples.
Tuple(&'static [Ty]),
/// Enum with one variant of each given type.
Enum(&'static [Ty]),
/// A struct with `arity` fields of type `ty`.
BigStruct { arity: usize, ty: &'static Ty },
/// A enum with `arity` variants of type `ty`.
@ -46,12 +48,23 @@ pub fn sub_tys(&self, ctor: &Constructor<Cx>) -> Vec<Self> {
match (ctor, *self) {
(Struct, Ty::Tuple(tys)) => tys.iter().copied().collect(),
(Struct, Ty::BigStruct { arity, ty }) => (0..arity).map(|_| *ty).collect(),
(Variant(i), Ty::Enum(tys)) => vec![tys[*i]],
(Variant(_), Ty::BigEnum { ty, .. }) => vec![*ty],
(Bool(..) | IntRange(..) | NonExhaustive | Missing | Wildcard, _) => vec![],
_ => panic!("Unexpected ctor {ctor:?} for type {self:?}"),
}
}
fn is_empty(&self) -> bool {
match *self {
Ty::Bool | Ty::U8 => false,
Ty::Tuple(tys) => tys.iter().any(|ty| ty.is_empty()),
Ty::Enum(tys) => tys.iter().all(|ty| ty.is_empty()),
Ty::BigStruct { arity, ty } => arity != 0 && ty.is_empty(),
Ty::BigEnum { arity, ty } => arity == 0 || ty.is_empty(),
}
}
pub fn ctor_set(&self) -> ConstructorSet<Cx> {
match *self {
Ty::Bool => ConstructorSet::Bool,
@ -64,10 +77,32 @@ pub fn ctor_set(&self) -> ConstructorSet<Cx> {
range_2: None,
},
Ty::Tuple(..) | Ty::BigStruct { .. } => ConstructorSet::Struct { empty: false },
Ty::BigEnum { arity, .. } => ConstructorSet::Variants {
variants: (0..arity).map(|_| VariantVisibility::Visible).collect(),
Ty::Enum(tys) if tys.is_empty() => ConstructorSet::NoConstructors,
Ty::Enum(tys) => ConstructorSet::Variants {
variants: tys
.iter()
.map(|ty| {
if ty.is_empty() {
VariantVisibility::Empty
} else {
VariantVisibility::Visible
}
})
.collect(),
non_exhaustive: false,
},
Ty::BigEnum { arity: 0, .. } => ConstructorSet::NoConstructors,
Ty::BigEnum { arity, ty } => {
let vis = if ty.is_empty() {
VariantVisibility::Empty
} else {
VariantVisibility::Visible
};
ConstructorSet::Variants {
variants: (0..arity).map(|_| vis).collect(),
non_exhaustive: false,
}
}
}
}
@ -79,6 +114,7 @@ pub fn write_variant_name(
match (*self, ctor) {
(Ty::Tuple(..), _) => Ok(()),
(Ty::BigStruct { .. }, _) => write!(f, "BigStruct"),
(Ty::Enum(..), Constructor::Variant(i)) => write!(f, "Enum::Variant{i}"),
(Ty::BigEnum { .. }, Constructor::Variant(i)) => write!(f, "BigEnum::Variant{i}"),
_ => write!(f, "{:?}::{:?}", self, ctor),
}
@ -119,7 +155,7 @@ fn is_exhaustive_patterns_feature_on(&self) -> bool {
}
fn is_min_exhaustive_patterns_feature_on(&self) -> bool {
false
true
}
fn ctor_arity(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> usize {

View File

@ -76,3 +76,17 @@ fn test_nested() {
Struct(Variant.1, Variant.1),
));
}
#[test]
fn test_empty() {
// `TY = Result<bool, !>`
const TY: Ty = Ty::Enum(&[Ty::Bool, Ty::Enum(&[])]);
assert_exhaustive(pats!(TY;
Variant.0,
));
let ty = Ty::Tuple(&[Ty::Bool, TY]);
assert_exhaustive(pats!(ty;
(true, Variant.0),
(false, Variant.0),
));
}

View File

@ -67,4 +67,24 @@ fn test_nested() {
),
&[&[], &[]],
);
let ty = Ty::Tuple(&[Ty::Bool; 3]);
assert_intersects(
pats!(ty;
(true, true, _),
(true, _, true),
(false, _, _),
),
&[&[], &[], &[]],
);
let ty = Ty::Tuple(&[Ty::Bool, Ty::Bool, Ty::U8]);
assert_intersects(
pats!(ty;
(true, _, _),
(_, true, 0..10),
(_, true, 10..),
(_, true, 3),
_,
),
&[&[], &[], &[], &[1], &[0, 1, 2, 3]],
);
}