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