summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2015-08-24 12:56:24 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2015-08-24 13:02:22 -0700
commit6fd1fdb4aadf309fb60540d52108445f71272646 (patch)
tree51040480396185b484bcb978e7883cab854f1e72
parent3bfbab3b8e1b86d861dbacc46e26259ebc3d839e (diff)
downloadscala-6fd1fdb4aadf309fb60540d52108445f71272646.tar.gz
scala-6fd1fdb4aadf309fb60540d52108445f71272646.tar.bz2
scala-6fd1fdb4aadf309fb60540d52108445f71272646.zip
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).
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala16
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala18
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)