about summary refs log tree commit diff
path: root/compiler/rustc_pattern_analysis/tests
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2024-07-21 14:37:10 +0200
committerNadrieril <nadrieril+git@gmail.com>2024-07-24 08:02:55 +0200
commitc4d6a4a7e4d8d006f6d08345e91fb1cdf0fc7e7a (patch)
treef928b13162e1584a36ce52042f6df841b5f68b6b /compiler/rustc_pattern_analysis/tests
parentbab8ede76130b4ca6e1652dbfe2d5d0fb8174495 (diff)
downloadrust-c4d6a4a7e4d8d006f6d08345e91fb1cdf0fc7e7a.tar.gz
rust-c4d6a4a7e4d8d006f6d08345e91fb1cdf0fc7e7a.zip
Add some tests
Diffstat (limited to 'compiler/rustc_pattern_analysis/tests')
-rw-r--r--compiler/rustc_pattern_analysis/tests/common/mod.rs44
-rw-r--r--compiler/rustc_pattern_analysis/tests/exhaustiveness.rs14
-rw-r--r--compiler/rustc_pattern_analysis/tests/intersection.rs20
3 files changed, 74 insertions, 4 deletions
diff --git a/compiler/rustc_pattern_analysis/tests/common/mod.rs b/compiler/rustc_pattern_analysis/tests/common/mod.rs
index 6e8bb505005..68ec75b7705 100644
--- a/compiler/rustc_pattern_analysis/tests/common/mod.rs
+++ b/compiler/rustc_pattern_analysis/tests/common/mod.rs
@@ -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 @@ impl Ty {
         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 @@ impl Ty {
                 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 @@ impl Ty {
         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 @@ impl PatCx for Cx {
     }
 
     fn is_min_exhaustive_patterns_feature_on(&self) -> bool {
-        false
+        true
     }
 
     fn ctor_arity(&self, ctor: &Constructor<Self>, ty: &Self::Ty) -> usize {
diff --git a/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs b/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs
index 4f8d68d5514..205d430d495 100644
--- a/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs
+++ b/compiler/rustc_pattern_analysis/tests/exhaustiveness.rs
@@ -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),
+    ));
+}
diff --git a/compiler/rustc_pattern_analysis/tests/intersection.rs b/compiler/rustc_pattern_analysis/tests/intersection.rs
index 4a96b7248da..8c8cb3c796d 100644
--- a/compiler/rustc_pattern_analysis/tests/intersection.rs
+++ b/compiler/rustc_pattern_analysis/tests/intersection.rs
@@ -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]],
+    );
 }