Skip to content

Commit c4d6a4a

Browse files
committed
Add some tests
1 parent bab8ede commit c4d6a4a

File tree

3 files changed

+74
-4
lines changed

3 files changed

+74
-4
lines changed

Diff for: compiler/rustc_pattern_analysis/tests/common/mod.rs

+40-4
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@ pub fn init_tracing() {
2525

2626
/// A simple set of types.
2727
#[allow(dead_code)]
28-
#[derive(Debug, Copy, Clone)]
28+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
2929
pub enum Ty {
3030
/// Booleans
3131
Bool,
3232
/// 8-bit unsigned integers
3333
U8,
3434
/// Tuples.
3535
Tuple(&'static [Ty]),
36+
/// Enum with one variant of each given type.
37+
Enum(&'static [Ty]),
3638
/// A struct with `arity` fields of type `ty`.
3739
BigStruct { arity: usize, ty: &'static Ty },
3840
/// A enum with `arity` variants of type `ty`.
@@ -46,12 +48,23 @@ impl Ty {
4648
match (ctor, *self) {
4749
(Struct, Ty::Tuple(tys)) => tys.iter().copied().collect(),
4850
(Struct, Ty::BigStruct { arity, ty }) => (0..arity).map(|_| *ty).collect(),
51+
(Variant(i), Ty::Enum(tys)) => vec![tys[*i]],
4952
(Variant(_), Ty::BigEnum { ty, .. }) => vec![*ty],
5053
(Bool(..) | IntRange(..) | NonExhaustive | Missing | Wildcard, _) => vec![],
5154
_ => panic!("Unexpected ctor {ctor:?} for type {self:?}"),
5255
}
5356
}
5457

58+
fn is_empty(&self) -> bool {
59+
match *self {
60+
Ty::Bool | Ty::U8 => false,
61+
Ty::Tuple(tys) => tys.iter().any(|ty| ty.is_empty()),
62+
Ty::Enum(tys) => tys.iter().all(|ty| ty.is_empty()),
63+
Ty::BigStruct { arity, ty } => arity != 0 && ty.is_empty(),
64+
Ty::BigEnum { arity, ty } => arity == 0 || ty.is_empty(),
65+
}
66+
}
67+
5568
pub fn ctor_set(&self) -> ConstructorSet<Cx> {
5669
match *self {
5770
Ty::Bool => ConstructorSet::Bool,
@@ -64,10 +77,32 @@ impl Ty {
6477
range_2: None,
6578
},
6679
Ty::Tuple(..) | Ty::BigStruct { .. } => ConstructorSet::Struct { empty: false },
67-
Ty::BigEnum { arity, .. } => ConstructorSet::Variants {
68-
variants: (0..arity).map(|_| VariantVisibility::Visible).collect(),
80+
Ty::Enum(tys) if tys.is_empty() => ConstructorSet::NoConstructors,
81+
Ty::Enum(tys) => ConstructorSet::Variants {
82+
variants: tys
83+
.iter()
84+
.map(|ty| {
85+
if ty.is_empty() {
86+
VariantVisibility::Empty
87+
} else {
88+
VariantVisibility::Visible
89+
}
90+
})
91+
.collect(),
6992
non_exhaustive: false,
7093
},
94+
Ty::BigEnum { arity: 0, .. } => ConstructorSet::NoConstructors,
95+
Ty::BigEnum { arity, ty } => {
96+
let vis = if ty.is_empty() {
97+
VariantVisibility::Empty
98+
} else {
99+
VariantVisibility::Visible
100+
};
101+
ConstructorSet::Variants {
102+
variants: (0..arity).map(|_| vis).collect(),
103+
non_exhaustive: false,
104+
}
105+
}
71106
}
72107
}
73108

@@ -79,6 +114,7 @@ impl Ty {
79114
match (*self, ctor) {
80115
(Ty::Tuple(..), _) => Ok(()),
81116
(Ty::BigStruct { .. }, _) => write!(f, "BigStruct"),
117+
(Ty::Enum(..), Constructor::Variant(i)) => write!(f, "Enum::Variant{i}"),
82118
(Ty::BigEnum { .. }, Constructor::Variant(i)) => write!(f, "BigEnum::Variant{i}"),
83119
_ => write!(f, "{:?}::{:?}", self, ctor),
84120
}
@@ -119,7 +155,7 @@ impl PatCx for Cx {
119155
}
120156

121157
fn is_min_exhaustive_patterns_feature_on(&self) -> bool {
122-
false
158+
true
123159
}
124160

125161
fn ctor_arity(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> usize {

Diff for: compiler/rustc_pattern_analysis/tests/exhaustiveness.rs

+14
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,17 @@ fn test_nested() {
7676
Struct(Variant.1, Variant.1),
7777
));
7878
}
79+
80+
#[test]
81+
fn test_empty() {
82+
// `TY = Result<bool, !>`
83+
const TY: Ty = Ty::Enum(&[Ty::Bool, Ty::Enum(&[])]);
84+
assert_exhaustive(pats!(TY;
85+
Variant.0,
86+
));
87+
let ty = Ty::Tuple(&[Ty::Bool, TY]);
88+
assert_exhaustive(pats!(ty;
89+
(true, Variant.0),
90+
(false, Variant.0),
91+
));
92+
}

Diff for: compiler/rustc_pattern_analysis/tests/intersection.rs

+20
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,24 @@ fn test_nested() {
6767
),
6868
&[&[], &[]],
6969
);
70+
let ty = Ty::Tuple(&[Ty::Bool; 3]);
71+
assert_intersects(
72+
pats!(ty;
73+
(true, true, _),
74+
(true, _, true),
75+
(false, _, _),
76+
),
77+
&[&[], &[], &[]],
78+
);
79+
let ty = Ty::Tuple(&[Ty::Bool, Ty::Bool, Ty::U8]);
80+
assert_intersects(
81+
pats!(ty;
82+
(true, _, _),
83+
(_, true, 0..10),
84+
(_, true, 10..),
85+
(_, true, 3),
86+
_,
87+
),
88+
&[&[], &[], &[], &[1], &[0, 1, 2, 3]],
89+
);
7090
}

0 commit comments

Comments
 (0)