about summary refs log tree commit diff
path: root/compiler/rustc_pattern_analysis/src/constructor.rs
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2023-12-11 13:32:34 +0100
committerNadrieril <nadrieril+git@gmail.com>2023-12-15 16:57:36 +0100
commitb111b2e8390c4fe0b1a5c1c8a7e75f7ca7df9fcf (patch)
treeb8680383ff6d19cdea4194ec7d39c7fe7454a90e /compiler/rustc_pattern_analysis/src/constructor.rs
parent4d1bd0db7f489b22c6d8aa2385937a95412c015b (diff)
downloadrust-b111b2e8390c4fe0b1a5c1c8a7e75f7ca7df9fcf.tar.gz
rust-b111b2e8390c4fe0b1a5c1c8a7e75f7ca7df9fcf.zip
Split `Single` ctor into more specific variants
Diffstat (limited to 'compiler/rustc_pattern_analysis/src/constructor.rs')
-rw-r--r--compiler/rustc_pattern_analysis/src/constructor.rs48
1 files changed, 35 insertions, 13 deletions
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs
index 3bca7894a29..95ffece54f3 100644
--- a/compiler/rustc_pattern_analysis/src/constructor.rs
+++ b/compiler/rustc_pattern_analysis/src/constructor.rs
@@ -631,11 +631,16 @@ impl OpaqueId {
 /// `Fields`.
 #[derive(Clone, Debug, PartialEq)]
 pub enum Constructor<'tcx> {
-    /// The constructor for patterns that have a single constructor, like tuples, struct patterns,
-    /// and references. Fixed-length arrays are treated separately with `Slice`.
-    Single,
+    /// Tuples and structs.
+    Struct,
     /// Enum variants.
     Variant(VariantIdx),
+    /// References
+    Ref,
+    /// Array and slice patterns.
+    Slice(Slice),
+    /// Union field accesses.
+    UnionField,
     /// Booleans
     Bool(bool),
     /// Ranges of integer literal values (`2`, `2..=5` or `2..5`).
@@ -645,8 +650,6 @@ pub enum Constructor<'tcx> {
     F64Range(IeeeFloat<DoubleS>, IeeeFloat<DoubleS>, RangeEnd),
     /// String literals. Strings are not quite the same as `&[u8]` so we treat them separately.
     Str(Const<'tcx>),
-    /// Array and slice patterns.
-    Slice(Slice),
     /// Constants that must not be matched structurally. They are treated as black boxes for the
     /// purposes of exhaustiveness: we must not inspect them, and they don't count towards making a
     /// match exhaustive.
@@ -723,7 +726,9 @@ impl<'tcx> Constructor<'tcx> {
             // Only a wildcard pattern can match these special constructors.
             (Missing { .. } | NonExhaustive | Hidden, _) => false,
 
-            (Single, Single) => true,
+            (Struct, Struct) => true,
+            (Ref, Ref) => true,
+            (UnionField, UnionField) => true,
             (Variant(self_id), Variant(other_id)) => self_id == other_id,
             (Bool(self_b), Bool(other_b)) => self_b == other_b,
 
@@ -786,12 +791,15 @@ pub enum VariantVisibility {
 /// `exhaustive_patterns` feature.
 #[derive(Debug)]
 pub enum ConstructorSet {
-    /// The type has a single constructor, e.g. `&T` or a struct. `empty` tracks whether the
-    /// constructor is empty.
-    Single { empty: bool },
+    /// The type is a tuple or struct. `empty` tracks whether the type is empty.
+    Struct { empty: bool },
     /// This type has the following list of constructors. If `variants` is empty and
     /// `non_exhaustive` is false, don't use this; use `NoConstructors` instead.
     Variants { variants: IndexVec<VariantIdx, VariantVisibility>, non_exhaustive: bool },
+    /// The type is `&T`.
+    Ref,
+    /// The type is a union.
+    Union,
     /// Booleans.
     Bool,
     /// The type is spanned by integer values. The range or ranges give the set of allowed values.
@@ -866,13 +874,27 @@ impl ConstructorSet {
         }
 
         match self {
-            ConstructorSet::Single { empty } => {
+            ConstructorSet::Struct { empty } => {
                 if !seen.is_empty() {
-                    present.push(Single);
+                    present.push(Struct);
                 } else if *empty {
-                    missing_empty.push(Single);
+                    missing_empty.push(Struct);
+                } else {
+                    missing.push(Struct);
+                }
+            }
+            ConstructorSet::Ref => {
+                if !seen.is_empty() {
+                    present.push(Ref);
+                } else {
+                    missing.push(Ref);
+                }
+            }
+            ConstructorSet::Union => {
+                if !seen.is_empty() {
+                    present.push(UnionField);
                 } else {
-                    missing.push(Single);
+                    missing.push(UnionField);
                 }
             }
             ConstructorSet::Variants { variants, non_exhaustive } => {