summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-02-10 17:35:24 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2016-02-12 15:55:30 -0800
commitbaee820b32f6e71907658ad6386e0d79e726e761 (patch)
tree22b74ce039725acb6755a6bf46f0b53f30b44f9d
parentda3f7177232e7c0732d5b7d2929dbb8271d7b395 (diff)
downloadscala-baee820b32f6e71907658ad6386e0d79e726e761.tar.gz
scala-baee820b32f6e71907658ad6386e0d79e726e761.tar.bz2
scala-baee820b32f6e71907658ad6386e0d79e726e761.zip
SI-9540 typedFunction is erasure aware
When typer is running during erasure, must assign erased FunctionType in typedFunction. This removes a bunch of unneeded casts now we no longer assign a half-erased FunctionType. I poked around a bit, and it looks like erasure doesn't want typer to erase built-in types (like Unit/Any/Nothing). They are already treated specially during erasure.
-rw-r--r--src/compiler/scala/tools/nsc/transform/Delambdafy.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala11
-rw-r--r--test/files/run/delambdafy_t6028.check4
3 files changed, 13 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
index f15d05f7df..f7ec9391a7 100644
--- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
+++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
@@ -127,9 +127,8 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
// turns a lambda into a new class def, a New expression instantiating that class
private def transformFunction(originalFunction: Function): TransformedFunction = {
- val functionTpe = originalFunction.tpe
- val targs = functionTpe.typeArgs
- val formals :+ restpe = targs
+ val formals = originalFunction.vparams.map(_.tpe)
+ val restpe = originalFunction.body.tpe.deconst
val oldClass = originalFunction.symbol.enclClass
// find which variables are free in the lambda because those are captures that need to be
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 3a8edafd58..783db65b33 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -128,6 +128,13 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
def canTranslateEmptyListToNil = true
def missingSelectErrorTree(tree: Tree, qual: Tree, name: Name): Tree = tree
+ // when type checking during erasure, generate erased types in spots that aren't transformed by erasure
+ // (it erases in TypeTrees, but not in, e.g., the type a Function node)
+ def phasedAppliedType(sym: Symbol, args: List[Type]) = {
+ val tp = appliedType(sym, args)
+ if (phase.erasedTypes) erasure.specialScalaErasure(tp) else tp
+ }
+
def typedDocDef(docDef: DocDef, mode: Mode, pt: Type): Tree =
typed(docDef.definition, mode, pt)
@@ -2983,7 +2990,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val formals = vparamSyms map (_.tpe)
val body1 = typed(fun.body, respt)
val restpe = packedType(body1, fun.symbol).deconst.resultType
- val funtpe = appliedType(FunctionSymbol, formals :+ restpe: _*)
+ val funtpe = phasedAppliedType(FunctionSymbol, formals :+ restpe)
treeCopy.Function(fun, vparams, body1) setType funtpe
}
@@ -3215,7 +3222,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
// less expensive than including them in inferMethodAlternative (see below).
def shapeType(arg: Tree): Type = arg match {
case Function(vparams, body) =>
- functionType(vparams map (_ => AnyTpe), shapeType(body))
+ functionType(vparams map (_ => AnyTpe), shapeType(body)) // TODO: should this be erased when retyping during erasure?
case AssignOrNamedArg(Ident(name), rhs) =>
NamedType(name, shapeType(rhs))
case _ =>
diff --git a/test/files/run/delambdafy_t6028.check b/test/files/run/delambdafy_t6028.check
index c8c4b1cb4c..b5a6e4b64e 100644
--- a/test/files/run/delambdafy_t6028.check
+++ b/test/files/run/delambdafy_t6028.check
@@ -11,7 +11,7 @@ package <empty> {
def foo(methodParam: String): Function0 = {
val methodLocal: String = "";
{
- (() => T.this.$anonfun$1(methodParam, methodLocal)).$asInstanceOf[Function0]()
+ (() => T.this.$anonfun$1(methodParam, methodLocal))
}
};
def bar(barParam: String): Object = {
@@ -21,7 +21,7 @@ package <empty> {
def tryy(tryyParam: String): Function0 = {
var tryyLocal: runtime.ObjectRef = scala.runtime.ObjectRef.create("");
{
- (() => T.this.$anonfun$2(tryyParam, tryyLocal)).$asInstanceOf[Function0]()
+ (() => T.this.$anonfun$2(tryyParam, tryyLocal))
}
};
final <artifact> private[this] def $anonfun$1(methodParam$1: String, methodLocal$1: String): String = T.this.classParam.+(T.this.field()).+(methodParam$1).+(methodLocal$1);