diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-01-14 19:57:04 -0800 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-01-14 19:57:04 -0800 |
commit | 2d4ed8e795b814f3d71bc6bb4949e4c2a5510da8 (patch) | |
tree | ee970ad7879d50ce97347de91132ff1149ac745a | |
parent | a3e85a54d6227cbc89e4999e838343b53b2a704c (diff) | |
parent | fdca5081fd5e9bdefba04ab015ba7f81f79bf6b9 (diff) | |
download | scala-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.scala | 19 | ||||
-rw-r--r-- | test/files/neg/t5189_inferred.check | 6 | ||||
-rw-r--r-- | test/files/neg/t5189_inferred.scala | 8 |
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 |