From d7545ec36bde6a21e5f3edb1b5982e801a53f6a9 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 12 Mar 2013 22:45:13 +0100 Subject: Simplify interplay between Uncurry Info- and Tree-Transformers Now, the InfoTransformer is responsible for erasing the path dependent types of formal parameters, at the same place where it flattens nested method types. This is preferable to having the tree transformer overwrite the result of the info transformer, as used to be the case after my previous work on SI-6135 / 493197fc. --- .../scala/tools/nsc/transform/UnCurry.scala | 27 ++++++++-------------- .../scala/reflect/internal/transform/UnCurry.scala | 11 +++++++-- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 66328e23bb..2c191096d6 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -818,7 +818,8 @@ abstract class UnCurry extends InfoTransform * * This transformation erases the dependent method types by: * - Widening the formal parameter type to existentially abstract - * over the prior parameters (using `packSymbols`) + * over the prior parameters (using `packSymbols`). This transformation + * is performed in the the `InfoTransform`er [[scala.reflect.internal.transform.UnCurry]]. * - Inserting casts in the method body to cast to the original, * precise type. * @@ -846,15 +847,14 @@ abstract class UnCurry extends InfoTransform */ def erase(dd: DefDef): (List[List[ValDef]], Tree) = { import dd.{ vparamss, rhs } - val vparamSyms = vparamss flatMap (_ map (_.symbol)) - val paramTransforms: List[ParamTransform] = - vparamss.flatten.map { p => - val declaredType = p.symbol.info - // existentially abstract over value parameters - val packedType = typer.packSymbols(vparamSyms, declaredType) - if (packedType =:= declaredType) Identity(p) + map2(vparamss.flatten, dd.symbol.info.paramss.flatten) { (p, infoParam) => + val packedType = infoParam.info + if (packedType =:= p.symbol.info) Identity(p) else { + // The Uncurry info transformer existentially abstracted over value parameters + // from the previous parameter lists. + // Change the type of the param symbol p.symbol updateInfo packedType @@ -866,8 +866,8 @@ abstract class UnCurry extends InfoTransform // the method body to refer to this, rather than the parameter. val tempVal: ValDef = { val tempValName = unit freshTermName (p.name + "$") - val newSym = dd.symbol.newTermSymbol(tempValName, p.pos, SYNTHETIC).setInfo(declaredType) - atPos(p.pos)(ValDef(newSym, gen.mkAttributedCast(Ident(p.symbol), declaredType))) + val newSym = dd.symbol.newTermSymbol(tempValName, p.pos, SYNTHETIC).setInfo(p.symbol.info) + atPos(p.pos)(ValDef(newSym, gen.mkAttributedCast(Ident(p.symbol), p.symbol.info))) } Packed(newParam, tempVal) } @@ -885,13 +885,6 @@ abstract class UnCurry extends InfoTransform Block(tempVals, rhsSubstituted) } - // update the type of the method after uncurry. - dd.symbol updateInfo { - val GenPolyType(tparams, tp) = dd.symbol.info - logResult("erased dependent param types for ${dd.symbol.info}") { - GenPolyType(tparams, MethodType(allParams map (_.symbol), tp.finalResultType)) - } - } (allParams :: Nil, rhs1) } } diff --git a/src/reflect/scala/reflect/internal/transform/UnCurry.scala b/src/reflect/scala/reflect/internal/transform/UnCurry.scala index 6dc6a0f7b8..00c7c3de9a 100644 --- a/src/reflect/scala/reflect/internal/transform/UnCurry.scala +++ b/src/reflect/scala/reflect/internal/transform/UnCurry.scala @@ -17,7 +17,14 @@ trait UnCurry { val tp = expandAlias(tp0) tp match { case MethodType(params, MethodType(params1, restpe)) => - apply(MethodType(params ::: params1, restpe)) + // This transformation is described in UnCurryTransformer.dependentParamTypeErasure + val packSymbolsMap = new TypeMap { + // Wrapping in a TypeMap to reuse the code that opts for a fast path if the function is an identity. + def apply(tp: Type): Type = packSymbols(params, tp) + } + val existentiallyAbstractedParam1s = packSymbolsMap.mapOver(params1) + val substitutedResult = restpe.substSym(params1, existentiallyAbstractedParam1s) + apply(MethodType(params ::: existentiallyAbstractedParam1s, substitutedResult)) case MethodType(params, ExistentialType(tparams, restpe @ MethodType(_, _))) => abort("unexpected curried method types with intervening existential") case MethodType(h :: t, restpe) if h.isImplicit => @@ -60,4 +67,4 @@ trait UnCurry { */ def transformInfo(sym: Symbol, tp: Type): Type = if (sym.isType) uncurryType(tp) else uncurry(tp) -} \ No newline at end of file +} -- cgit v1.2.3