1
+ #![ allow( dead_code) ]
1
2
use rustc_pattern_analysis:: constructor:: {
2
3
Constructor , ConstructorSet , IntRange , MaybeInfiniteInt , RangeEnd , VariantVisibility ,
3
4
} ;
@@ -22,8 +23,10 @@ fn init_tracing() {
22
23
. try_init ( ) ;
23
24
}
24
25
26
+ pub const UNIT : Ty = Ty :: Tuple ( & [ ] ) ;
27
+ pub const NEVER : Ty = Ty :: Enum ( & [ ] ) ;
28
+
25
29
/// A simple set of types.
26
- #[ allow( dead_code) ]
27
30
#[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
28
31
pub ( super ) enum Ty {
29
32
/// Booleans
@@ -38,6 +41,8 @@ pub(super) enum Ty {
38
41
BigStruct { arity : usize , ty : & ' static Ty } ,
39
42
/// A enum with `arity` variants of type `ty`.
40
43
BigEnum { arity : usize , ty : & ' static Ty } ,
44
+ /// Like `Enum` but non-exhaustive.
45
+ NonExhaustiveEnum ( & ' static [ Ty ] ) ,
41
46
}
42
47
43
48
/// The important logic.
@@ -47,7 +52,7 @@ impl Ty {
47
52
match ( ctor, * self ) {
48
53
( Struct , Ty :: Tuple ( tys) ) => tys. iter ( ) . copied ( ) . collect ( ) ,
49
54
( Struct , Ty :: BigStruct { arity, ty } ) => ( 0 ..arity) . map ( |_| * ty) . collect ( ) ,
50
- ( Variant ( i) , Ty :: Enum ( tys) ) => vec ! [ tys[ * i] ] ,
55
+ ( Variant ( i) , Ty :: Enum ( tys) | Ty :: NonExhaustiveEnum ( tys ) ) => vec ! [ tys[ * i] ] ,
51
56
( Variant ( _) , Ty :: BigEnum { ty, .. } ) => vec ! [ * ty] ,
52
57
( Bool ( ..) | IntRange ( ..) | NonExhaustive | Missing | Wildcard , _) => vec ! [ ] ,
53
58
_ => panic ! ( "Unexpected ctor {ctor:?} for type {self:?}" ) ,
@@ -61,6 +66,7 @@ impl Ty {
61
66
Ty :: Enum ( tys) => tys. iter ( ) . all ( |ty| ty. is_empty ( ) ) ,
62
67
Ty :: BigStruct { arity, ty } => arity != 0 && ty. is_empty ( ) ,
63
68
Ty :: BigEnum { arity, ty } => arity == 0 || ty. is_empty ( ) ,
69
+ Ty :: NonExhaustiveEnum ( ..) => false ,
64
70
}
65
71
}
66
72
@@ -90,6 +96,19 @@ impl Ty {
90
96
. collect ( ) ,
91
97
non_exhaustive : false ,
92
98
} ,
99
+ Ty :: NonExhaustiveEnum ( tys) => ConstructorSet :: Variants {
100
+ variants : tys
101
+ . iter ( )
102
+ . map ( |ty| {
103
+ if ty. is_empty ( ) {
104
+ VariantVisibility :: Empty
105
+ } else {
106
+ VariantVisibility :: Visible
107
+ }
108
+ } )
109
+ . collect ( ) ,
110
+ non_exhaustive : true ,
111
+ } ,
93
112
Ty :: BigEnum { arity : 0 , .. } => ConstructorSet :: NoConstructors ,
94
113
Ty :: BigEnum { arity, ty } => {
95
114
let vis = if ty. is_empty ( ) {
@@ -113,7 +132,9 @@ impl Ty {
113
132
match ( * self , ctor) {
114
133
( Ty :: Tuple ( ..) , _) => Ok ( ( ) ) ,
115
134
( Ty :: BigStruct { .. } , _) => write ! ( f, "BigStruct" ) ,
116
- ( Ty :: Enum ( ..) , Constructor :: Variant ( i) ) => write ! ( f, "Enum::Variant{i}" ) ,
135
+ ( Ty :: Enum ( ..) | Ty :: NonExhaustiveEnum ( ..) , Constructor :: Variant ( i) ) => {
136
+ write ! ( f, "Enum::Variant{i}" )
137
+ }
117
138
( Ty :: BigEnum { .. } , Constructor :: Variant ( i) ) => write ! ( f, "BigEnum::Variant{i}" ) ,
118
139
_ => write ! ( f, "{:?}::{:?}" , self , ctor) ,
119
140
}
0 commit comments