Skip to content

Commit da9511d

Browse files
committed
add GADT test
1 parent d681a78 commit da9511d

File tree

3 files changed

+73
-14
lines changed

3 files changed

+73
-14
lines changed

src/dotty/tools/dotc/transform/patmat/Space.scala

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -266,19 +266,12 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
266266
Empty
267267
}
268268

269-
/** Is `tp1` a subtype of `tp2`?
270-
*
271-
* Ignore type parameters in comparison due to erasure, i.e., Some[Int] <: Some[T]
272-
*/
273-
def isSubType(tp1: Type, tp2: Type): Boolean = (tp1, tp2) match {
274-
case (tp1: RefinedType, tp2: RefinedType) => isSubType(tp1.parent, tp2.parent)
275-
case (tp1: RefinedType, _) => isSubType(tp1.parent, tp2)
276-
case (_, tp2: RefinedType) => isSubType(tp1, tp2.parent)
277-
case (_, _) => tp1 <:< tp2
278-
}
269+
/** Is `tp1` a subtype of `tp2`? */
270+
def isSubType(tp1: Type, tp2: Type): Boolean = tp1 <:< tp2
279271

280272
def isEqualType(tp1: Type, tp2: Type): Boolean = tp1 =:= tp2
281273

274+
/** Parameter types of the case class type `tp` */
282275
def signature(tp: Type): List[Type] = {
283276
val ktor = tp.classSymbol.primaryConstructor.info
284277

@@ -325,10 +318,14 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
325318
else if (sym.info.typeParams.length > 0 || tp.isInstanceOf[TypeRef])
326319
refine(tp, sym.asClass.classInfo.symbolicTypeRef)
327320
else
328-
sym.info
329-
} filter(_ <:< tp) // child may not always be subtype of parent: SI-4020
330-
331-
parts.map(tp => Typ(tp, true))
321+
sym.typeRef
322+
} filter { tpe =>
323+
// Child class may not always be subtype of parent:
324+
// GADT & path-dependent types
325+
isSubType(tpe, tp)
326+
}
327+
328+
parts.map(Typ(_, true))
332329
}
333330
}
334331

tests/patmat/gadt.check

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
./tests/patmat/gadt.scala:13: warning: match may not be exhaustive.
2+
It would fail on the following input: IntLit(_)
3+
def foo1b(x: Expr[Int]) = x match {
4+
^
5+
./tests/patmat/gadt.scala:22: warning: match may not be exhaustive.
6+
It would fail on the following input: Or(_, _)
7+
def foo2b(x: Expr[Boolean]) = x match {
8+
^
9+
./tests/patmat/gadt.scala:45: warning: match may not be exhaustive.
10+
It would fail on the following input: BooleanLit(_), IntLit(_)
11+
def foo4b(x: Expr) = x match {
12+
^
13+
three warnings found

tests/patmat/gadt.scala

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
object Test {
2+
sealed trait Expr[T]
3+
case class IntLit(i: Int) extends Expr[Int]
4+
case class BooleanLit(b: Boolean) extends Expr[Boolean]
5+
case class Sum(l: Expr[Int], r: Expr[Int]) extends Expr[Int]
6+
case class Or(l: Expr[Boolean], r: Expr[Boolean]) extends Expr[Boolean]
7+
8+
def foo1a(x: Expr[Int]) = x match {
9+
case _: IntLit => true
10+
case _: Sum => true
11+
}
12+
13+
def foo1b(x: Expr[Int]) = x match {
14+
case _: Sum => true
15+
}
16+
17+
def foo2a(x: Expr[Boolean]) = x match {
18+
case _: BooleanLit => true
19+
case _: Or => true
20+
}
21+
22+
def foo2b(x: Expr[Boolean]) = x match {
23+
case _: BooleanLit => true
24+
}
25+
26+
def foo3a(x: Expr[Boolean]) = x match {
27+
case _: BooleanLit => true
28+
case _: Or => true
29+
// case _: Sum => true
30+
}
31+
32+
def foo3b(x: Expr[Int]) = x match {
33+
case _: IntLit => true
34+
case _: Sum => true
35+
// case _: Or => true
36+
}
37+
38+
def foo4a(x: Expr) = x match {
39+
case _: IntLit => true
40+
case _: Sum => true
41+
case _: BooleanLit => true
42+
case _: Or => true
43+
}
44+
45+
def foo4b(x: Expr) = x match {
46+
case _: Sum => true
47+
case _: Or => true
48+
}
49+
}

0 commit comments

Comments
 (0)