From 6fd1fdb4aadf309fb60540d52108445f71272646 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Mon, 24 Aug 2015 12:56:24 -0700 Subject: Uncurry does Literal RHS for ConstantType def, not Constructors Uncurry seems more logical to me. Ideally, Erasure would erase ConstantTypes, since they do not exist in bytecode. In any case, doing this earlier, when we're rewriting method anyway, simplifies constructors, which should be focussing on, well, constructors (& fields). --- .../scala/tools/nsc/transform/Constructors.scala | 16 +++------------- src/compiler/scala/tools/nsc/transform/UnCurry.scala | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index 2828e87bd8..6ecdd2b195 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -631,21 +631,11 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { // recurse on class definition, store in defBuf case _: ClassDef => defBuf += new ConstructorTransformer(unit).transform(stat) - // all methods except the primary constructor go into template + // methods (except primary constructor) go into template + // (non-primary ctors --> auxConstructorBuf / regular defs --> defBuf) case _: DefDef if statSym.isPrimaryConstructor => () case _: DefDef if statSym.isConstructor => auxConstructorBuf += stat - - // other methods go to defBuf - // methods with ConstantType result get the corresponding Literal for their RHS - case _: DefDef => - val resTp = statSym.info.resultType - def mkLiteral(rhs: Tree) = gen.mkAttributedQualifier(resTp) setPos rhs.pos - - val literalized = - if (resTp.isInstanceOf[ConstantType] && statSym.info.params.isEmpty) deriveDefDef(stat)(mkLiteral) - else stat - - defBuf += literalized + case _: DefDef => defBuf += stat // val defs with constant right-hand sides are eliminated. case _: ValDef if statSym.info.isInstanceOf[ConstantType] => () diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 72e2174bf8..79a77d7a0c 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -582,6 +582,7 @@ abstract class UnCurry extends InfoTransform } case dd @ DefDef(_, _, _, vparamss0, _, rhs0) => + val ddSym = dd.symbol val (newParamss, newRhs): (List[List[ValDef]], Tree) = if (dependentParamTypeErasure isDependent dd) dependentParamTypeErasure erase dd @@ -593,11 +594,22 @@ abstract class UnCurry extends InfoTransform (vparamss1, rhs0) } + // A no-arg method with ConstantType result type can safely be reduced to the corresponding Literal + // (only pure methods are typed as ConstantType). We could also do this for methods with arguments, + // after ensuring the arguments are not referenced. + val literalRhsIfConst = + if (newParamss.head.isEmpty) { // We know newParamss.length == 1 from above + ddSym.info.resultType match { + case tp@ConstantType(value) => Literal(value) setType tp setPos newRhs.pos // inlining of gen.mkAttributedQualifier(tp) + case _ => newRhs + } + } else newRhs + val flatdd = copyDefDef(dd)( vparamss = newParamss, - rhs = nonLocalReturnKeys get dd.symbol match { - case Some(k) => atPos(newRhs.pos)(nonLocalReturnTry(newRhs, k, dd.symbol)) - case None => newRhs + rhs = nonLocalReturnKeys get ddSym match { + case Some(k) => atPos(newRhs.pos)(nonLocalReturnTry(literalRhsIfConst, k, ddSym)) + case None => literalRhsIfConst } ) addJavaVarargsForwarders(dd, flatdd) -- cgit v1.2.3