summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-04-23 23:55:05 +0200
committerJason Zaugg <jzaugg@gmail.com>2013-04-24 10:09:25 +0200
commit62713964b96f64f9c0fd0070c89aa6571679856d (patch)
tree36141e60bec629274a7b716386672f8e3d897509 /test
parentd484c17dbc47559dad8a7ae544d14a285cdfb8b2 (diff)
downloadscala-62713964b96f64f9c0fd0070c89aa6571679856d.tar.gz
scala-62713964b96f64f9c0fd0070c89aa6571679856d.tar.bz2
scala-62713964b96f64f9c0fd0070c89aa6571679856d.zip
SI-7369 Avoid spurious unreachable warnings in patterns
Unreachability analysis draws on the enumerated domain of types (e.g sealed subclasses + null, or true/false), and also looks at all stable identifier patterns tested for equality against the same 'slot' in a pattern. It was drawing the wrong conclusions about stable identifier patterns. Unlike the domain constants, two such values may hold the same value, so we can't assume that matching X precludes matching Y in the same slot in a subsequent case. For example: val X: Boolean = true; val Y: Boolean = true def m1(t1: Tuple1[Boolean]) = t1 match { case Tuple1(true) => case Tuple1(false) => case Tuple1(false) => // correctly unreachable } def m2(t1: Tuple1[Boolean]) = t1 match { case Tuple1(X) => case Tuple1(Y) => // spurious unreachable warning } // // Before // reachability, vars: V2: Boolean ::= true | false// Set(false, Y, X, true) // = x1._1 V1: (Boolean,) ::= null | ... // = x1 equality axioms: V2=true#4 \/ V2=false#5 /\ -V2=false#5 \/ -V2=Y#3 /\ -V2=false#5 \/ -V2=X#2 /\ -V2=false#5 \/ -V2=true#4 /\ -V2=Y#3 \/ -V2=X#2 /\ -V2=Y#3 \/ -V2=true#4 /\ -V2=X#2 \/ -V2=true#4 // // After // reachability, vars: V2: Boolean ::= true | false// Set(false, Y, X, true) // = x1._1 V1: (Boolean,) ::= null | ... // = x1 equality axioms: V2=true#4 \/ V2=false#5 /\ -V2=false#5 \/ -V2=true#4
Diffstat (limited to 'test')
-rw-r--r--test/files/neg/t7369.check13
-rw-r--r--test/files/neg/t7369.flags1
-rw-r--r--test/files/neg/t7369.scala43
-rw-r--r--test/files/pos/t7369.flags1
-rw-r--r--test/files/pos/t7369.scala37
5 files changed, 95 insertions, 0 deletions
diff --git a/test/files/neg/t7369.check b/test/files/neg/t7369.check
new file mode 100644
index 0000000000..4f101e145a
--- /dev/null
+++ b/test/files/neg/t7369.check
@@ -0,0 +1,13 @@
+t7369.scala:6: error: unreachable code
+ case Tuple1(X) => // unreachable
+ ^
+t7369.scala:13: error: unreachable code
+ case Tuple1(true) => // unreachable
+ ^
+t7369.scala:31: error: unreachable code
+ case Tuple1(X) => // unreachable
+ ^
+t7369.scala:40: error: unreachable code
+ case Tuple1(null) => // unreachable
+ ^
+four errors found
diff --git a/test/files/neg/t7369.flags b/test/files/neg/t7369.flags
new file mode 100644
index 0000000000..e8fb65d50c
--- /dev/null
+++ b/test/files/neg/t7369.flags
@@ -0,0 +1 @@
+-Xfatal-warnings \ No newline at end of file
diff --git a/test/files/neg/t7369.scala b/test/files/neg/t7369.scala
new file mode 100644
index 0000000000..87ddfe98b7
--- /dev/null
+++ b/test/files/neg/t7369.scala
@@ -0,0 +1,43 @@
+object Test {
+ val X, Y = true
+ (null: Tuple1[Boolean]) match {
+ case Tuple1(X) =>
+ case Tuple1(Y) =>
+ case Tuple1(X) => // unreachable
+ case _ =>
+ }
+
+ (null: Tuple1[Boolean]) match {
+ case Tuple1(true) =>
+ case Tuple1(false) =>
+ case Tuple1(true) => // unreachable
+ case _ =>
+ }
+}
+
+
+sealed abstract class B;
+case object True extends B;
+case object False extends B;
+
+object Test2 {
+
+ val X: B = True
+ val Y: B = False
+
+ (null: Tuple1[B]) match {
+ case Tuple1(X) =>
+ case Tuple1(Y) =>
+ case Tuple1(X) => // unreachable
+ case _ =>
+ }
+}
+
+object Test3 {
+ (null: Tuple1[B]) match {
+ case Tuple1(null) =>
+ case Tuple1(True) =>
+ case Tuple1(null) => // unreachable
+ case _ =>
+ }
+}
diff --git a/test/files/pos/t7369.flags b/test/files/pos/t7369.flags
new file mode 100644
index 0000000000..85d8eb2ba2
--- /dev/null
+++ b/test/files/pos/t7369.flags
@@ -0,0 +1 @@
+-Xfatal-warnings
diff --git a/test/files/pos/t7369.scala b/test/files/pos/t7369.scala
new file mode 100644
index 0000000000..2f31c93d29
--- /dev/null
+++ b/test/files/pos/t7369.scala
@@ -0,0 +1,37 @@
+object Test {
+ val X, Y = true
+ (null: Tuple1[Boolean]) match {
+ case Tuple1(X) =>
+ case Tuple1(Y) => // unreachable
+ case _ =>
+ }
+}
+
+
+sealed abstract class B;
+case object True extends B;
+case object False extends B;
+
+object Test2 {
+
+ val X: B = True
+ val Y: B = False
+
+ (null: Tuple1[B]) match {
+ case Tuple1(X) =>
+ case Tuple1(Y) => // no warning
+ case _ =>
+ }
+}
+
+object Test3 {
+ val X, O = true
+ def classify(neighbourhood: (Boolean, Boolean, Boolean)): String = {
+ neighbourhood match {
+ case (X, X, X) => "middle"
+ case (X, X, O) => "right"
+ case (O, X, X) => "left"
+ case _ => throw new IllegalArgumentException("Invalid")
+ }
+ }
+} \ No newline at end of file