@@ -29,7 +29,6 @@ import config.Printers.{ exhaustivity => debug }
29
29
* 3. A union of spaces `S1 | S2 | ...` is a space
30
30
* 4. For a case class Kon(x1: T1, x2: T2, .., xn: Tn), if S1, S2, ..., Sn
31
31
* are spaces, then `Kon(S1, S2, ..., Sn)` is a space.
32
- * 5. A constant `Const(value, T)` is a point in space
33
32
*
34
33
* For the problem of exhaustivity check, its formulation in terms of space is as follows:
35
34
*
@@ -67,12 +66,6 @@ case class Kon(tp: Type, params: List[Space]) extends Space
67
66
/** Union of spaces */
68
67
case class Or (spaces : List [Space ]) extends Space
69
68
70
- /** Point in space */
71
- sealed trait Point extends Space
72
-
73
- /** Point representing literal constants in patterns */
74
- case class Const (value : Constant , tp : Type ) extends Point
75
-
76
69
/** abstract space logic */
77
70
trait SpaceLogic {
78
71
/** Is `tp1` a subtype of `tp2`? */
@@ -157,11 +150,6 @@ trait SpaceLogic {
157
150
simplify(minus(a, b)) == Empty
158
151
case (Kon (tp1, ss1), Kon (tp2, ss2)) =>
159
152
isEqualType(tp1, tp2) && ss1.zip(ss2).forall((isSubspace _).tupled)
160
- case (Const (v1, _), Const (v2, _)) => v1 == v2
161
- case (Const (_, tp1), Typ (tp2, _)) => isSubType(tp1, tp2) || tryDecompose2(tp2)
162
- case (Const (_, _), Or (ss)) => ss.exists(isSubspace(a, _))
163
- case (Const (_, _), _) => false
164
- case (_, Const (_, _)) => false
165
153
}
166
154
167
155
debug.println(s " ${show(a)} < ${show(b)} = $res" )
@@ -198,18 +186,6 @@ trait SpaceLogic {
198
186
if (! isEqualType(tp1, tp2)) Empty
199
187
else if (ss1.zip(ss2).exists(p => simplify(intersect(p._1, p._2)) == Empty )) Empty
200
188
else Kon (tp1, ss1.zip(ss2).map((intersect _).tupled))
201
- case (Const (v1, _), Const (v2, _)) =>
202
- if (v1 == v2) a else Empty
203
- case (Const (_, tp1), Typ (tp2, _)) =>
204
- if (isSubType(tp1, tp2)) a
205
- else if (canDecompose(tp2)) tryDecompose2(tp2)
206
- else Empty
207
- case (Const (_, _), _) => Empty
208
- case (Typ (tp1, _), Const (_, tp2)) =>
209
- if (isSubType(tp2, tp1)) b
210
- else if (canDecompose(tp1)) tryDecompose1(tp1)
211
- else Empty
212
- case (_, Const (_, _)) => Empty
213
189
}
214
190
215
191
debug.println(s " ${show(a)} & ${show(b)} = ${show(res)}" )
@@ -255,17 +231,6 @@ trait SpaceLogic {
255
231
Or (ss1.zip(ss2).map((minus _).tupled).zip(0 to ss2.length - 1 ).map {
256
232
case (ri, i) => Kon (tp1, ss1.updated(i, ri))
257
233
})
258
- case (Const (v1, _), Const (v2, _)) =>
259
- if (v1 == v2) Empty else a
260
- case (Const (_, tp1), Typ (tp2, _)) =>
261
- if (isSubType(tp1, tp2)) Empty
262
- else if (canDecompose(tp2)) tryDecompose2(tp2)
263
- else a
264
- case (Const (_, _), _) => a
265
- case (Typ (tp1, _), Const (_, tp2)) => // Boolean & Java enum
266
- if (canDecompose(tp1)) tryDecompose1(tp1)
267
- else a
268
- case (_, Const (_, _)) => a
269
234
}
270
235
271
236
debug.println(s " ${show(a)} - ${show(b)} = ${show(res)}" )
@@ -284,17 +249,14 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
284
249
* otherwise approximate extractors to Empty
285
250
*/
286
251
def project (pat : Tree , roundUp : Boolean = true )(implicit ctx : Context ): Space = pat match {
287
- case Literal (c) => Const (c, c.tpe)
252
+ case Literal (c) =>
253
+ if (c.value.isInstanceOf [Symbol ])
254
+ Typ (c.value.asInstanceOf [Symbol ].termRef, false )
255
+ else
256
+ Typ (ConstantType (c), false )
288
257
case _ : BackquotedIdent => Typ (pat.tpe, false )
289
258
case Ident (_) | Select (_, _) =>
290
- pat.tpe.stripAnnots match {
291
- case tp : TermRef =>
292
- if (pat.symbol.is(Enum ))
293
- Const (Constant (pat.symbol), tp)
294
- else
295
- Typ (tp, false )
296
- case tp => Typ (tp, false )
297
- }
259
+ Typ (pat.tpe.stripAnnots, false )
298
260
case Alternative (trees) => Or (trees.map(project(_, roundUp)))
299
261
case Bind (_, pat) => project(pat)
300
262
case UnApply (_, _, pats) =>
@@ -366,11 +328,11 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
366
328
case OrType (tp1, tp2) => List (Typ (tp1, true ), Typ (tp2, true ))
367
329
case _ if tp =:= ctx.definitions.BooleanType =>
368
330
List (
369
- Const ( Constant (true ), ctx.definitions. BooleanType ),
370
- Const ( Constant (false ), ctx.definitions. BooleanType )
331
+ Typ ( ConstantType ( Constant (true )), true ),
332
+ Typ ( ConstantType ( Constant (false )), true )
371
333
)
372
334
case _ if tp.classSymbol.is(Enum ) =>
373
- children.map(sym => Const ( Constant ( sym), tp ))
335
+ children.map(sym => Typ ( sym.termRef, true ))
374
336
case _ =>
375
337
val parts = children.map { sym =>
376
338
if (sym.is(ModuleClass ))
@@ -419,7 +381,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
419
381
tp.classSymbol.is(allOf(Trait , Sealed )) ||
420
382
tp.isInstanceOf [OrType ] ||
421
383
tp =:= ctx.definitions.BooleanType ||
422
- tp.classSymbol.is(Enum )
384
+ tp.classSymbol.is(allOf( Enum , Sealed )) // Enum value doesn't have Sealed flag
423
385
424
386
debug.println(s " decomposable: ${tp.show} = $res" )
425
387
@@ -475,7 +437,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
475
437
def show (s : Space ): String = {
476
438
def doShow (s : Space , mergeList : Boolean = false ): String = s match {
477
439
case Empty => " "
478
- case Const (v , _) => v .show
440
+ case Typ ( c : ConstantType , _) => c.value .show
479
441
case Typ (tp : TermRef , _) => tp.symbol.showName
480
442
case Typ (tp, decomposed) =>
481
443
val sym = tp.widen.classSymbol
0 commit comments