aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-08-16 11:55:57 +0200
committerMartin Odersky <odersky@gmail.com>2014-08-16 11:56:07 +0200
commit7d414eb69b28fa0f6855168aa7afe43a75b3f23e (patch)
treec6410e0331a0f43bde6876337db21415e0f81235 /src
parentc54cd3e0503144f362ecb000109b75a0a53b3165 (diff)
downloaddotty-7d414eb69b28fa0f6855168aa7afe43a75b3f23e.tar.gz
dotty-7d414eb69b28fa0f6855168aa7afe43a75b3f23e.tar.bz2
dotty-7d414eb69b28fa0f6855168aa7afe43a75b3f23e.zip
Roll Uncurry into Erasure
Making cpy recompute types uncovered errors in uncurry. In a nutshell, the intermediate Apply nodes of a curried function were ill-typed, which caused errors produced by TypeAssigner. These nodes were eliminated down the road, but the errors are already issued. I did not find a good way to treat uncurry as a treetransform. Since it is rather trivial, it did not seem warranted to make it a full transformer either. So in the end the uncurry functionality became part of erasure.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/Compiler.scala4
-rw-r--r--src/dotty/tools/dotc/core/transform/Erasure.scala12
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala27
-rw-r--r--src/dotty/tools/dotc/transform/UncurryTreeTransform.scala46
4 files changed, 31 insertions, 58 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index fffcfd8f8..cae8c5782 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -32,9 +32,7 @@ class Compiler {
new TypeTestsCasts,
new InterceptedMethods,
new Literalize),
- List(new Erasure)//,
- //List(new UncurryTreeTransform
- // /* , new Constructors */)
+ List(new Erasure)
)
var runId = 1
diff --git a/src/dotty/tools/dotc/core/transform/Erasure.scala b/src/dotty/tools/dotc/core/transform/Erasure.scala
index 41254c982..19662d22a 100644
--- a/src/dotty/tools/dotc/core/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/core/transform/Erasure.scala
@@ -107,7 +107,8 @@ class Erasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wildcard
* - For T1 & T2, erasure(T1) (??)
* - For T1 | T2, the first base class in the linearization of T which is also a base class of T2
* - For a method type (Fs)scala.Unit, (|Fs|)scala.Unit.
- * - For any other method type (Fs)T, (|Fs|)|T|.
+ * - For any other uncurried method type (Fs)T, (|Fs|)|T|.
+ * - For a curried method type (Fs1)(Fs2)T, (|Fs1|,Es2)ET where (Es2)ET = |(Fs2)T|.
* - For a polymorphic type, the erasure of its result type.
* - For the class info type of java.lang.Object, the same type without any parents.
* - For a class info type of a value class, the same type without any parents.
@@ -140,8 +141,13 @@ class Erasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wildcard
this(tp.baseTypeRef(lubClass(tp1, tp2)))
case tp: MethodType =>
val paramErasure = erasureFn(tp.isJava, isSemi, isConstructor, wildcardOK)(_)
- tp.derivedMethodType(
- tp.paramNames, tp.paramTypes.mapConserve(paramErasure), eraseResult(tp.resultType))
+ val formals = tp.paramTypes.mapConserve(paramErasure)
+ eraseResult(tp.resultType) match {
+ case rt: MethodType =>
+ tp.derivedMethodType(tp.paramNames ++ rt.paramNames, formals ++ rt.paramTypes, rt.resultType)
+ case rt =>
+ tp.derivedMethodType(tp.paramNames, formals, rt)
+ }
case tp: PolyType =>
this(tp.resultType)
case tp @ ClassInfo(pre, cls, classParents, decls, _) =>
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala
index 6b2a5a676..f02846735 100644
--- a/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/transform/Erasure.scala
@@ -264,13 +264,28 @@ object Erasure {
override def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = {
val Apply(fun, args) = tree
- val fun1 = typedExpr(fun, WildcardType)
- fun1.tpe.widen match {
- case mt: MethodType =>
- val args1 = args.zipWithConserve(mt.paramTypes)(typedExpr)
- untpd.cpy.Apply(tree)(fun1, args1) withType mt.resultType
+ fun match {
+ case fun: Apply =>
+ typedApply(fun, pt)(ctx.fresh.setTree(tree))
case _ =>
- throw new MatchError(i"tree $tree has uxpected type of function ${fun1.tpe.widen}, was ${fun.typeOpt.widen}")
+ def nextOuter(ctx: Context): Context =
+ if (ctx.outer.tree eq tree) nextOuter(ctx.outer) else ctx.outer
+ def contextArgs(tree: untpd.Apply)(implicit ctx: Context): List[untpd.Tree] =
+ ctx.tree match {
+ case enclApp @ Apply(enclFun, enclArgs) if enclFun eq tree =>
+ enclArgs ++ contextArgs(enclApp)(nextOuter(ctx))
+ case _ =>
+ Nil
+ }
+ val allArgs = args ++ contextArgs(tree)
+ val fun1 = typedExpr(fun, WildcardType)
+ fun1.tpe.widen match {
+ case mt: MethodType =>
+ val allArgs1 = allArgs.zipWithConserve(mt.paramTypes)(typedExpr)
+ untpd.cpy.Apply(tree)(fun1, allArgs1) withType mt.resultType
+ case _ =>
+ throw new MatchError(i"tree $tree has unexpected type of function ${fun1.tpe.widen}, was ${fun.typeOpt.widen}")
+ }
}
}
diff --git a/src/dotty/tools/dotc/transform/UncurryTreeTransform.scala b/src/dotty/tools/dotc/transform/UncurryTreeTransform.scala
deleted file mode 100644
index cf7668079..000000000
--- a/src/dotty/tools/dotc/transform/UncurryTreeTransform.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-package dotty.tools.dotc
-package transform
-
-import TreeTransforms._
-import core.DenotTransformers._
-import core.Denotations._
-import core.SymDenotations._
-import core.Contexts._
-import core.Types._
-import core.Symbols._
-import ast.Trees._
-import ast.tpd.{Apply, Tree, cpy}
-
-class UncurryTreeTransform extends MiniPhaseTransform with InfoTransformer {
-
- override def name: String = "uncurry"
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree =
- ctx.traceIndented(s"transforming ${tree.show}", show = true) {
- tree.fun match {
- case Apply(fn, args) =>
- def showType(implicit ctx: Context) =
- ctx.log(s"at ${ctx.phase} ${fn.symbol} has type ${fn.symbol.info.widen.show}")
- showType
- ctx.atNextPhase(showType(_))
- showType
- cpy.Apply(tree)(tree.fun, args ++ tree.args)
- case _ => tree
- }}
-
- def uncurry(tp: Type)(implicit ctx: Context): Type = tp match {
- case tp @ MethodType(pnames1, ptypes1) =>
- tp.resultType match {
- case rt @ MethodType(pnames2, ptypes2) =>
- tp.derivedMethodType(pnames1 ++ pnames2, ptypes1 ++ ptypes2, rt.resultType)
- case _ =>
- tp
- }
- case tp: PolyType =>
- tp.derivedPolyType(tp.paramNames, tp.paramBounds, uncurry(tp.resultType))
- case _ =>
- tp
- }
-
- def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type =
- uncurry(tp)
-} \ No newline at end of file