summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2013-01-14 19:57:04 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-01-14 19:57:04 -0800
commit2d4ed8e795b814f3d71bc6bb4949e4c2a5510da8 (patch)
treeee970ad7879d50ce97347de91132ff1149ac745a
parenta3e85a54d6227cbc89e4999e838343b53b2a704c (diff)
parentfdca5081fd5e9bdefba04ab015ba7f81f79bf6b9 (diff)
downloadscala-2d4ed8e795b814f3d71bc6bb4949e4c2a5510da8.tar.gz
scala-2d4ed8e795b814f3d71bc6bb4949e4c2a5510da8.tar.bz2
scala-2d4ed8e795b814f3d71bc6bb4949e4c2a5510da8.zip
Merge pull request #1877 from adriaanm/rebase-1876-master
SI-5189 detect unsoundness when inferring type of match
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala19
-rw-r--r--test/files/neg/t5189_inferred.check6
-rw-r--r--test/files/neg/t5189_inferred.scala8
3 files changed, 16 insertions, 17 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 96a93e2a20..20907979e9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2433,21 +2433,7 @@ trait Typers extends 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
- }
-
- // undo adaptConstrPattern's evil deeds, as they confuse the old pattern matcher
- // the flags are used to avoid accidentally deskolemizing unrelated skolems of skolems
- object deskolemizeGADTSkolems extends TypeMap {
- def apply(tp: Type): Type = mapOver(tp) match {
- case TypeRef(pre, sym, args) if sym.isGADTSkolem =>
- typeRef(NoPrefix, sym.deSkolemize, args)
- case tp1 => tp1
- }
+ treeCopy.CaseDef(cdef, pat1, guard1, body1) setType body1.tpe
}
def typedCases(cases: List[CaseDef], pattp: Type, pt: Type): List[CaseDef] =
@@ -2492,12 +2478,11 @@ trait Typers extends Adaptations with Tags {
// Match(EmptyTree, cases) ==> new PartialFunction { def apply<OrElse>(params) = `translateMatch('`(param1,...,paramN)` match { cases }')` }
// for fresh params, the selector of the match we'll translated simply gathers those in a tuple
// NOTE: restricted to PartialFunction -- leave Function trees if the expected type does not demand a partial function
- class MatchFunTyper(tree: Tree, cases: List[CaseDef], mode: Mode, pt0: Type) {
+ class MatchFunTyper(tree: Tree, cases: List[CaseDef], mode: Mode, pt: Type) {
// TODO: remove FunctionN support -- this is currently designed so that it can emit FunctionN and PartialFunction subclasses
// however, we should leave Function nodes until Uncurry so phases after typer can still detect normal Function trees
// we need to synthesize PartialFunction impls, though, to avoid nastiness in Uncurry in transforming&duplicating generated pattern matcher trees
// TODO: remove PartialFunction support from UnCurry
- private val pt = deskolemizeGADTSkolems(pt0)
private val targs = pt.normalize.typeArgs
private val arity = if (isFunctionType(pt)) targs.length - 1 else 1 // TODO pt should always be a (Partial)Function, right?
private val ptRes = if (targs.isEmpty) WildcardType else targs.last // may not be fully defined
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