Skip to content

Commit cc02243

Browse files
committed
add test set for exhaustivity and redundancy check
1 parent 1a7618f commit cc02243

File tree

136 files changed

+3184
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

136 files changed

+3184
-0
lines changed

tests/patmat/NonAbstractSealed.check

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
./tests/patmat/NonAbstractSealed.scala:6: warning: match may not be exhaustive.
2+
It would fail on the following input: _: A
3+
(null: A) match {
4+
^
5+
one warning found

tests/patmat/NonAbstractSealed.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
sealed class A
2+
class B extends A
3+
class C extends A
4+
5+
object Test {
6+
(null: A) match {
7+
case t: B =>
8+
case t: C =>
9+
}
10+
}

tests/patmat/TwoTrait.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
object Test {
2+
sealed trait A
3+
sealed trait B
4+
5+
abstract sealed class Parent
6+
class Foo extends Parent with A with B
7+
class Bar extends Parent with B with A
8+
9+
(null: A) match {
10+
case _: B =>
11+
}
12+
}

tests/patmat/aladdin1055/A.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object A {
2+
sealed trait T { def f: Int }
3+
class TT extends T { def f = 0 }
4+
5+
def foo = new T { def f = 1 } // local subclass of sealed trait T
6+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def foo(t: A.T) = t match {
3+
case a: A.TT => 0
4+
}
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
./tests/patmat/aladdin1055/Test_1.scala:2: warning: match may not be exhaustive.
2+
It would fail on the following input: (_ : this.<local child>)
3+
def foo(t: A.T) = t match {
4+
^
5+
one warning found

tests/patmat/enum/Day.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
public enum Day {
2+
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
3+
THURSDAY, FRIDAY, SATURDAY
4+
}

tests/patmat/enum/expected.check

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
./tests/patmat/enum/patmat-enum.scala:4: warning: match may not be exhaustive.
2+
It would fail on the following input: SATURDAY, FRIDAY, THURSDAY, SUNDAY
3+
day match {
4+
^
5+
./tests/patmat/enum/patmat-enum.scala:15: warning: match may not be exhaustive.
6+
It would fail on the following input: SATURDAY, FRIDAY, THURSDAY
7+
day match {
8+
^
9+
two warnings found

tests/patmat/enum/patmat-enum.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
object Test1 {
2+
val day: Day = ???
3+
4+
day match {
5+
case Day.MONDAY => true
6+
case Day.TUESDAY => true
7+
case Day.WEDNESDAY => true
8+
}
9+
}
10+
11+
object Test2 {
12+
import Day._
13+
val day: Day = ???
14+
15+
day match {
16+
case MONDAY => true
17+
case TUESDAY => true
18+
case WEDNESDAY => true
19+
case SUNDAY => true
20+
}
21+
}

tests/patmat/exhausting.check

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
./tests/patmat/exhausting.scala:21: warning: match may not be exhaustive.
2+
It would fail on the following input: List(_), List(_, _, _)
3+
def fail1[T](xs: List[T]) = xs match {
4+
^
5+
./tests/patmat/exhausting.scala:27: warning: match may not be exhaustive.
6+
It would fail on the following input: Nil
7+
def fail2[T](xs: List[T]) = xs match {
8+
^
9+
./tests/patmat/exhausting.scala:32: warning: match may not be exhaustive.
10+
It would fail on the following input: List(_, _)
11+
def fail3a(xs: List[Int]) = xs match {
12+
^
13+
./tests/patmat/exhausting.scala:39: warning: match may not be exhaustive.
14+
It would fail on the following input: Bar3
15+
def fail3[T](x: Foo[T]) = x match {
16+
^
17+
./tests/patmat/exhausting.scala:44: warning: match may not be exhaustive.
18+
It would fail on the following input: (Bar2, Bar2)
19+
def fail4[T <: AnyRef](xx: (Foo[T], Foo[T])) = xx match {
20+
^
21+
./tests/patmat/exhausting.scala:53: warning: match may not be exhaustive.
22+
It would fail on the following input: (Bar2, Bar2), (Bar2, Bar1), (Bar1, Bar3), (Bar1, Bar2)
23+
def fail5[T](xx: (Foo[T], Foo[T])) = xx match {
24+
^
25+
6 warnings found

tests/patmat/exhausting.scala

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
object Test {
2+
sealed abstract class Foo[T]
3+
case object Bar1 extends Foo[Int]
4+
case object Bar2 extends Foo[String]
5+
case object Bar3 extends Foo[Any]
6+
7+
def ex1[T](xs: List[T]) = xs match {
8+
case ys: List[_] => "ok"
9+
}
10+
def ex2[T](xx: (Foo[T], Foo[T])) = xx match {
11+
case (Bar1, Bar1) => ()
12+
case (_, Bar1) => ()
13+
case (_, Bar3) => ()
14+
case (_, Bar2) => ()
15+
}
16+
def ex3[T](xx: (Foo[T], Foo[T])) = xx match {
17+
case (_: Foo[_], _: Foo[_]) => ()
18+
}
19+
20+
// fails for: ::(_, Nil), ::(_, ::(_, ::(_, _))), ...
21+
def fail1[T](xs: List[T]) = xs match {
22+
case Nil => "ok"
23+
case x :: y :: Nil => "ok"
24+
}
25+
26+
// fails for: Nil
27+
def fail2[T](xs: List[T]) = xs match {
28+
case _ :: _ => "ok"
29+
}
30+
31+
// fails for: ::(<not in (2, 1)>, _)
32+
def fail3a(xs: List[Int]) = xs match {
33+
case 1 :: _ =>
34+
case 2 :: _ =>
35+
case Nil =>
36+
}
37+
38+
// fails for: Bar3
39+
def fail3[T](x: Foo[T]) = x match {
40+
case Bar1 => "ok"
41+
case Bar2 => "ok"
42+
}
43+
// fails for: (Bar2, Bar2)
44+
def fail4[T <: AnyRef](xx: (Foo[T], Foo[T])) = xx match {
45+
case (Bar1, Bar1) => ()
46+
case (Bar2, Bar3) => ()
47+
case (Bar3, _) => ()
48+
}
49+
// fails for: (Bar1, Bar2)
50+
// fails for: (Bar1, Bar3)
51+
// fails for: (Bar2, Bar1)
52+
// fails for: (Bar2, Bar2)
53+
def fail5[T](xx: (Foo[T], Foo[T])) = xx match {
54+
case (Bar1, Bar1) => ()
55+
case (Bar2, Bar3) => ()
56+
case (Bar3, _) => ()
57+
}
58+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// tests exhaustivity doesn't give warnings (due to its heuristic rewrites kicking in or it backing off)
2+
object Test {
3+
// List() => Nil
4+
List(1) match {
5+
case List() =>
6+
case x :: xs =>
7+
}
8+
9+
// we don't look into guards
10+
val turnOffChecks = true
11+
List(1) match {
12+
case _ if turnOffChecks =>
13+
}
14+
15+
// we back off when there are any user-defined extractors
16+
// in fact this is exhaustive, but we pretend we don't know since List's unapplySeq is not special to the compiler
17+
// to compensate our ignorance, we back off
18+
// well, in truth, we do rewrite List() to Nil, but otherwise we do nothing
19+
// the full rewrite List(a, b) to a :: b :: Nil, for example is planned (but not sure it's a good idea)
20+
List(true, false) match {
21+
case List(_, _, _:_*) =>
22+
case List(node, _:_*) =>
23+
case Nil =>
24+
}
25+
26+
}

tests/patmat/for.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def foo[A, B](l: List[(A, B)]): List[A] = {
3+
for ((a, b) <- l) yield a
4+
}
5+
}

tests/patmat/gadt.check

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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+
./tests/patmat/gadt.scala:55: warning: match may not be exhaustive.
14+
It would fail on the following input: Sum(_, _)
15+
def foo5b[T <: Int](x: Expr[T]) = x match {
16+
^
17+
four warnings found

tests/patmat/gadt.scala

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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+
50+
def foo5a[T <: Int](x: Expr[T]) = x match {
51+
case _: IntLit => true
52+
case _: Sum => true
53+
}
54+
55+
def foo5b[T <: Int](x: Expr[T]) = x match {
56+
case _: IntLit => true
57+
}
58+
}

tests/patmat/gadt2.scala.ignore

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
sealed trait Nat[+T]
2+
case class Zero() extends Nat[Nothing]
3+
case class Succ[T]() extends Nat[T]
4+
5+
sealed trait Vect[+N <: Nat[_], +T]
6+
case class VN[T]() extends Vect[Zero, T]
7+
case class VC[T, N <: Nat[_]](x: T, xs: Vect[N, T]) extends Vect[Succ[N], T]
8+
9+
object Test {
10+
def foo[N <: Nat[_], A, B](v1: Vect[N, A], v2: Vect[N, B]) = (v1, v2) match {
11+
case (VN(), VN()) => 1
12+
case (VC(x, xs), VC(y, ys)) => 2
13+
}
14+
}

tests/patmat/gadt3.scala.ignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
sealed trait Expr[T]
2+
case class IntExpr(x: Int) extends Expr[Int]
3+
case class BooleanExpr(b: Boolean) extends Expr[Boolean]
4+
5+
object Test {
6+
def foo[T](x: Expr[T], y: Expr[T]) = (x, y) match {
7+
case (IntExpr(_), IntExpr(_)) =>
8+
case (BooleanExpr(_), BooleanExpr(_)) =>
9+
}
10+
}

tests/patmat/i947.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
./tests/patmat/i947.scala:10: warning: unreachable code
2+
case ys: List[d18383] => false
3+
^
4+
one warning found

tests/patmat/i947.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
object Test {
2+
3+
class c {
4+
5+
private var x: Int = 0
6+
7+
override def equals(other: Any) = other match {
8+
case o: c => x == o.x
9+
case xs: List[c] => false
10+
case ys: List[d18383] => false
11+
case _ => false
12+
}
13+
14+
15+
}
16+
}

0 commit comments

Comments
 (0)