summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid MacIver <david.maciver@gmail.com>2008-10-25 10:44:40 +0000
committerDavid MacIver <david.maciver@gmail.com>2008-10-25 10:44:40 +0000
commit1f029a28d6d6c827158004417c62bec06b67d85c (patch)
tree5d9bcb660c295bddac4876c8a50f2bd4cff7cb04
parent17d9b4a800dd0cdb5de929f539061c8b6a19df44 (diff)
downloadscala-1f029a28d6d6c827158004417c62bec06b67d85c.tar.gz
scala-1f029a28d6d6c827158004417c62bec06b67d85c.tar.bz2
scala-1f029a28d6d6c827158004417c62bec06b67d85c.zip
Correct handling of unreachable code testing wh...
Correct handling of unreachable code testing when matching on primitives.
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala16
-rw-r--r--test/files/neg/unreachablechar.check4
-rw-r--r--test/files/neg/unreachablechar.scala8
-rw-r--r--test/pending/pos/t1164.scala29
-rw-r--r--test/pending/pos/t1260.scala17
5 files changed, 64 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 3b8c876bd2..e1bc8b1518 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -44,16 +44,11 @@ trait ParallelMatching {
def isSimpleSwitch: Boolean = {
(isSameType(scrutinee.tpe.widen, definitions.IntClass.tpe) ||
- isSameType(scrutinee.tpe.widen, definitions.CharClass.tpe)) && {
- var xs = column; while(!xs.isEmpty) { // forall
- val h = xs.head
- if (strip2(h).isInstanceOf[Literal] || isDefaultPattern(h))
- xs = xs.tail
- else
- return false
- }
- return true
- }}
+ isSameType(scrutinee.tpe.widen, definitions.CharClass.tpe)) &&
+ column.init.forall(h => strip2(h).isInstanceOf[Literal]) && {
+ val last = column.last;
+ last.isInstanceOf[Literal] || isDefaultPattern(last);
+ }}
// an unapply for which we don't need a type test
def isUnapplyHead(): Boolean = column.head match {
@@ -321,6 +316,7 @@ trait ParallelMatching {
private def sanity(pos:Position, tag: Int, pvars:List[Symbol]) {
varMap = (tag,pvars)::varMap
}
+
//lazy
private def bindVars(Tag:Int, orig: Binding): Binding = {
def myBindVars(rest:List[(Int,List[Symbol])], bnd: Binding): Binding = rest match {
diff --git a/test/files/neg/unreachablechar.check b/test/files/neg/unreachablechar.check
new file mode 100644
index 0000000000..7442e1178a
--- /dev/null
+++ b/test/files/neg/unreachablechar.check
@@ -0,0 +1,4 @@
+unreachablechar.scala:5: error: unreachable code
+ case 'f' => println("not stuff?");
+ ^
+one error found
diff --git a/test/files/neg/unreachablechar.scala b/test/files/neg/unreachablechar.scala
new file mode 100644
index 0000000000..94438ce321
--- /dev/null
+++ b/test/files/neg/unreachablechar.scala
@@ -0,0 +1,8 @@
+object Foo extends Application{
+ 'f' match {
+ case 'o'|'c'|'b' => println("Oooo");
+ case _ => println("stuff");
+ case 'f' => println("not stuff?");
+ }
+
+}
diff --git a/test/pending/pos/t1164.scala b/test/pending/pos/t1164.scala
new file mode 100644
index 0000000000..3acda88ba9
--- /dev/null
+++ b/test/pending/pos/t1164.scala
@@ -0,0 +1,29 @@
+
+
+object test {
+
+ class Foo[a](val arg : a)
+
+ object Foo {
+ def apply [a](arg : a, right :a) = new Foo[a](arg)
+ def unapply [a](m : Foo[a]) = Some (m.arg)
+ }
+
+ def matchAndGetArgFromFoo[a]( e:Foo[a]):a = {e match { case Foo(x) => x }}
+
+
+ // Try the same thing as above but use function as arguemnt to Bar
+ // constructor
+
+ type FunIntToA [a] = (int) => a
+ class Bar[a] (var f: FunIntToA[a])
+
+ object Bar {
+ def apply[a](f: FunIntToA[a]) = new Bar[a](f)
+ def unapply[a](m: Bar[a]) = Some (m.f)
+ }
+
+ def matchAndGetFunFromBar[a](b:Bar[a]) : FunIntToA[a] = { b match { case Bar(x) => x}}
+
+
+}
diff --git a/test/pending/pos/t1260.scala b/test/pending/pos/t1260.scala
new file mode 100644
index 0000000000..b05259998e
--- /dev/null
+++ b/test/pending/pos/t1260.scala
@@ -0,0 +1,17 @@
+case class Foo(a: String, b: String)
+
+object Bar {
+ def unapply(s: String): Option[Long] =
+ try { Some(s.toLong) } catch { case _ => None }
+}
+
+object Test {
+ def main(args: Array[String]) {
+ val f = Foo("1", "2")
+ f match {
+ case Foo(Bar(1), Bar(2)) => ()
+ case Foo(Bar(i), Bar(j)) if i >= 0 => ()
+ }
+ }
+}
+