summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2013-01-09 14:44:47 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-01-09 14:58:25 -0800
commit8fb19b132579b7ddb9dd12ae829451dcf9d91332 (patch)
tree2cb58cb3d90497d2086f66c0a195dfb1a04efce6
parent1381cda86ddeca1b9829a9c53ff9372cfd816735 (diff)
downloadscala-8fb19b132579b7ddb9dd12ae829451dcf9d91332.tar.gz
scala-8fb19b132579b7ddb9dd12ae829451dcf9d91332.tar.bz2
scala-8fb19b132579b7ddb9dd12ae829451dcf9d91332.zip
SI-5189 detect unsoundness when inferring type of match
GADT skolems encode type slack that results from pattern matching on variant type constructors I thought they would not longer be relevant after cases have been typed, and since they caused weird issues with the old pattern matcher, I deskolemized in typedCase however, when we don't have an expected type for the match, we need to keep the skolems around until the skolemized type makes it out of the match and it becomes the result of type inference for that match when you do have an expected type, it will propagate to the case-level and the confrontation will thus already take place when typing individual cases
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala11
-rw-r--r--test/files/neg/t5189_inferred.check6
-rw-r--r--test/files/neg/t5189_inferred.scala8
3 files changed, 19 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9d390476db..5fe223dde6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2523,11 +2523,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
// body1 = checkNoEscaping.locals(context.scope, pt, body1)
- val treeWithSkolems = treeCopy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe
-
- new TypeMapTreeSubstituter(deskolemizeGADTSkolems).traverse(treeWithSkolems)
-
- treeWithSkolems // now without skolems, actually
+ treeCopy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe
}
// undo adaptConstrPattern's evil deeds, as they confuse the old pattern matcher
@@ -2562,7 +2558,10 @@ trait Typers extends Modes with Adaptations with Tags {
val casesAdapted = if (!needAdapt) casesTyped else casesTyped map (adaptCase(_, mode, resTp))
- treeCopy.Match(tree, selector1, casesAdapted) setType resTp
+ val matchTyped = treeCopy.Match(tree, selector1, casesAdapted) setType resTp
+ if (!newPatternMatching) // TODO: remove this in 2.11 -- only needed for old pattern matcher
+ new TypeMapTreeSubstituter(deskolemizeGADTSkolems).traverse(matchTyped)
+ matchTyped
}
// match has been typed -- virtualize it if we're feeling experimental
diff --git a/test/files/neg/t5189_inferred.check b/test/files/neg/t5189_inferred.check
new file mode 100644
index 0000000000..9cc5dcc242
--- /dev/null
+++ b/test/files/neg/t5189_inferred.check
@@ -0,0 +1,6 @@
+t5189_inferred.scala:7: error: type mismatch;
+ found : scala.collection.immutable.Nil.type
+ required: ?A1 where type ?A1
+ f(Invariant(arr): Covariant[Any])(0) = Nil
+ ^
+one error found
diff --git a/test/files/neg/t5189_inferred.scala b/test/files/neg/t5189_inferred.scala
new file mode 100644
index 0000000000..e4e8765445
--- /dev/null
+++ b/test/files/neg/t5189_inferred.scala
@@ -0,0 +1,8 @@
+trait Covariant[+A]
+case class Invariant[A](xs: Array[A]) extends Covariant[A]
+
+class Test {
+ val arr = Array("abc")
+ def f[A](v: Covariant[A]) /*inferred!*/ = v match { case Invariant(xs) => xs }
+ f(Invariant(arr): Covariant[Any])(0) = Nil
+} \ No newline at end of file