diff options
author | Vlad Ureche <vlad.ureche@gmail.com> | 2015-08-23 03:55:48 +0200 |
---|---|---|
committer | Vlad Ureche <vlad.ureche@gmail.com> | 2015-08-23 15:25:50 +0200 |
commit | 6b336f86d677f5aedd40bd673cdd7ffbea780fbd (patch) | |
tree | 3021437d1ba7b848c6e126ca10474011ff2b615e /src/reflect | |
parent | f8a6d21a490090bac20b0753c46b91ca2b335049 (diff) | |
download | scala-6b336f86d677f5aedd40bd673cdd7ffbea780fbd.tar.gz scala-6b336f86d677f5aedd40bd673cdd7ffbea780fbd.tar.bz2 scala-6b336f86d677f5aedd40bd673cdd7ffbea780fbd.zip |
SI-9442 Fix the uncurry-erasure types
Using the "uncurry-erased" type (the one after the uncurry phase) can
lead to incorrect tree transformations. For example, compiling:
```
def foo(c: Ctx)(l: c.Tree): Unit = {
val l2: c.Tree = l
}
```
Results in the following AST:
```
def foo(c: Ctx, l: Ctx#Tree): Unit = {
val l$1: Ctx#Tree = l.asInstanceOf[Ctx#Tree]
val l2: c.Tree = l$1 // no, not really, it's not.
}
```
Of course, this is incorrect, since `l$1` has type `Ctx#Tree`, which is
not a subtype of `c.Tree`.
So what we need to do is to use the pre-uncurry type when creating
`l$1`, which is `c.Tree` and is correct. Now, there are two
additional problems:
1. when varargs and byname params are involved, the uncurry
transformation desugares these special cases to actual
typerefs, eg:
```
T* ~> Seq[T] (Scala-defined varargs)
T* ~> Array[T] (Java-defined varargs)
=>T ~> Function0[T] (by name params)
```
we use the DesugaredParameterType object (defined in
scala.reflect.internal.transform.UnCurry) to redo this desugaring
manually here
2. the type needs to be normalized, since `gen.mkCast` checks this
(no HK here, just aliases have to be expanded before handing the
type to `gen.mkAttributedCast`, which calls `gen.mkCast`)
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/scala/reflect/internal/transform/UnCurry.scala | 22 | ||||
-rw-r--r-- | src/reflect/scala/reflect/runtime/JavaUniverseForce.scala | 2 |
2 files changed, 16 insertions, 8 deletions
diff --git a/src/reflect/scala/reflect/internal/transform/UnCurry.scala b/src/reflect/scala/reflect/internal/transform/UnCurry.scala index abea8bed9f..85e3ac60e8 100644 --- a/src/reflect/scala/reflect/internal/transform/UnCurry.scala +++ b/src/reflect/scala/reflect/internal/transform/UnCurry.scala @@ -40,19 +40,27 @@ trait UnCurry { apply(MethodType(h.cloneSymbol.resetFlag(IMPLICIT) :: t, restpe)) case NullaryMethodType(restpe) => apply(MethodType(List(), restpe)) - case TypeRef(pre, ByNameParamClass, arg :: Nil) => - apply(functionType(List(), arg)) - case TypeRef(pre, RepeatedParamClass, arg :: Nil) => - apply(seqType(arg)) - case TypeRef(pre, JavaRepeatedParamClass, arg :: Nil) => - apply(arrayType( - if (isUnboundedGeneric(arg)) ObjectTpe else arg)) + case DesugaredParameterType(desugaredTpe) => + apply(desugaredTpe) case _ => expandAlias(mapOver(tp)) } } } + object DesugaredParameterType { + def unapply(tpe: Type): Option[Type] = tpe match { + case TypeRef(pre, ByNameParamClass, arg :: Nil) => + Some(functionType(List(), arg)) + case TypeRef(pre, RepeatedParamClass, arg :: Nil) => + Some(seqType(arg)) + case TypeRef(pre, JavaRepeatedParamClass, arg :: Nil) => + Some(arrayType(if (isUnboundedGeneric(arg)) ObjectTpe else arg)) + case _ => + None + } + } + private val uncurryType = new TypeMap { def apply(tp0: Type): Type = { val tp = expandAlias(tp0) diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index ea213cadd9..5477bdd6d4 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -444,7 +444,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.ScalaValueClassesNoUnit definitions.ScalaValueClasses - + uncurry.DesugaredParameterType erasure.GenericArray erasure.scalaErasure erasure.specialScalaErasure |