Skip to content

Commit 6fd1fdb

Browse files
committed
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).
1 parent 3bfbab3 commit 6fd1fdb

File tree

2 files changed

+18
-16
lines changed

2 files changed

+18
-16
lines changed

src/compiler/scala/tools/nsc/transform/Constructors.scala

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -631,21 +631,11 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL {
631631
// recurse on class definition, store in defBuf
632632
case _: ClassDef => defBuf += new ConstructorTransformer(unit).transform(stat)
633633

634-
// all methods except the primary constructor go into template
634+
// methods (except primary constructor) go into template
635+
// (non-primary ctors --> auxConstructorBuf / regular defs --> defBuf)
635636
case _: DefDef if statSym.isPrimaryConstructor => ()
636637
case _: DefDef if statSym.isConstructor => auxConstructorBuf += stat
637-
638-
// other methods go to defBuf
639-
// methods with ConstantType result get the corresponding Literal for their RHS
640-
case _: DefDef =>
641-
val resTp = statSym.info.resultType
642-
def mkLiteral(rhs: Tree) = gen.mkAttributedQualifier(resTp) setPos rhs.pos
643-
644-
val literalized =
645-
if (resTp.isInstanceOf[ConstantType] && statSym.info.params.isEmpty) deriveDefDef(stat)(mkLiteral)
646-
else stat
647-
648-
defBuf += literalized
638+
case _: DefDef => defBuf += stat
649639

650640
// val defs with constant right-hand sides are eliminated.
651641
case _: ValDef if statSym.info.isInstanceOf[ConstantType] => ()

src/compiler/scala/tools/nsc/transform/UnCurry.scala

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ abstract class UnCurry extends InfoTransform
582582
}
583583

584584
case dd @ DefDef(_, _, _, vparamss0, _, rhs0) =>
585+
val ddSym = dd.symbol
585586
val (newParamss, newRhs): (List[List[ValDef]], Tree) =
586587
if (dependentParamTypeErasure isDependent dd)
587588
dependentParamTypeErasure erase dd
@@ -593,11 +594,22 @@ abstract class UnCurry extends InfoTransform
593594
(vparamss1, rhs0)
594595
}
595596

597+
// A no-arg method with ConstantType result type can safely be reduced to the corresponding Literal
598+
// (only pure methods are typed as ConstantType). We could also do this for methods with arguments,
599+
// after ensuring the arguments are not referenced.
600+
val literalRhsIfConst =
601+
if (newParamss.head.isEmpty) { // We know newParamss.length == 1 from above
602+
ddSym.info.resultType match {
603+
case tp@ConstantType(value) => Literal(value) setType tp setPos newRhs.pos // inlining of gen.mkAttributedQualifier(tp)
604+
case _ => newRhs
605+
}
606+
} else newRhs
607+
596608
val flatdd = copyDefDef(dd)(
597609
vparamss = newParamss,
598-
rhs = nonLocalReturnKeys get dd.symbol match {
599-
case Some(k) => atPos(newRhs.pos)(nonLocalReturnTry(newRhs, k, dd.symbol))
600-
case None => newRhs
610+
rhs = nonLocalReturnKeys get ddSym match {
611+
case Some(k) => atPos(newRhs.pos)(nonLocalReturnTry(literalRhsIfConst, k, ddSym))
612+
case None => literalRhsIfConst
601613
}
602614
)
603615
addJavaVarargsForwarders(dd, flatdd)

0 commit comments

Comments
 (0)