@@ -29,7 +29,6 @@ import config.Printers.{ exhaustivity => debug }
2929 * 3. A union of spaces `S1 | S2 | ...` is a space
3030 * 4. For a case class Kon(x1: T1, x2: T2, .., xn: Tn), if S1, S2, ..., Sn
3131 * are spaces, then `Kon(S1, S2, ..., Sn)` is a space.
32- * 5. A constant `Const(value, T)` is a point in space
3332 *
3433 * For the problem of exhaustivity check, its formulation in terms of space is as follows:
3534 *
@@ -67,12 +66,6 @@ case class Kon(tp: Type, params: List[Space]) extends Space
6766/** Union of spaces */
6867case class Or (spaces : List [Space ]) extends Space
6968
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-
7669/** abstract space logic */
7770trait SpaceLogic {
7871 /** Is `tp1` a subtype of `tp2`? */
@@ -157,11 +150,6 @@ trait SpaceLogic {
157150 simplify(minus(a, b)) == Empty
158151 case (Kon (tp1, ss1), Kon (tp2, ss2)) =>
159152 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
165153 }
166154
167155 debug.println(s " ${show(a)} < ${show(b)} = $res" )
@@ -198,18 +186,6 @@ trait SpaceLogic {
198186 if (! isEqualType(tp1, tp2)) Empty
199187 else if (ss1.zip(ss2).exists(p => simplify(intersect(p._1, p._2)) == Empty )) Empty
200188 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
213189 }
214190
215191 debug.println(s " ${show(a)} & ${show(b)} = ${show(res)}" )
@@ -255,17 +231,6 @@ trait SpaceLogic {
255231 Or (ss1.zip(ss2).map((minus _).tupled).zip(0 to ss2.length - 1 ).map {
256232 case (ri, i) => Kon (tp1, ss1.updated(i, ri))
257233 })
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
269234 }
270235
271236 debug.println(s " ${show(a)} - ${show(b)} = ${show(res)}" )
@@ -284,17 +249,14 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
284249 * otherwise approximate extractors to Empty
285250 */
286251 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 )
288257 case _ : BackquotedIdent => Typ (pat.tpe, false )
289258 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 )
298260 case Alternative (trees) => Or (trees.map(project(_, roundUp)))
299261 case Bind (_, pat) => project(pat)
300262 case UnApply (_, _, pats) =>
@@ -366,11 +328,11 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
366328 case OrType (tp1, tp2) => List (Typ (tp1, true ), Typ (tp2, true ))
367329 case _ if tp =:= ctx.definitions.BooleanType =>
368330 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 )
371333 )
372334 case _ if tp.classSymbol.is(Enum ) =>
373- children.map(sym => Const ( Constant ( sym), tp ))
335+ children.map(sym => Typ ( sym.termRef, true ))
374336 case _ =>
375337 val parts = children.map { sym =>
376338 if (sym.is(ModuleClass ))
@@ -419,7 +381,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
419381 tp.classSymbol.is(allOf(Trait , Sealed )) ||
420382 tp.isInstanceOf [OrType ] ||
421383 tp =:= ctx.definitions.BooleanType ||
422- tp.classSymbol.is(Enum )
384+ tp.classSymbol.is(allOf( Enum , Sealed )) // Enum value doesn't have Sealed flag
423385
424386 debug.println(s " decomposable: ${tp.show} = $res" )
425387
@@ -475,7 +437,7 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
475437 def show (s : Space ): String = {
476438 def doShow (s : Space , mergeList : Boolean = false ): String = s match {
477439 case Empty => " "
478- case Const (v , _) => v .show
440+ case Typ ( c : ConstantType , _) => c.value .show
479441 case Typ (tp : TermRef , _) => tp.symbol.showName
480442 case Typ (tp, decomposed) =>
481443 val sym = tp.widen.classSymbol
0 commit comments