diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/UnCurry.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 870c35338c..eea1f53cbc 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -7,9 +7,10 @@ package scala package tools.nsc package transform -import symtab.Flags._ -import scala.collection.{ mutable, immutable } import scala.language.postfixOps + +import symtab.Flags._ +import scala.collection.mutable import scala.reflect.internal.util.ListOfNil /*<export> */ @@ -235,10 +236,7 @@ abstract class UnCurry extends InfoTransform !(specialized =:= fun.tpe) } - def canUseDelamdafyMethod = ( - (inConstructorFlag == 0) // Avoiding synthesizing code prone to SI-6666, SI-8363 by using old-style lambda translation - && (!isSpecialized || (settings.isBCodeActive && settings.target.value == "jvm-1.8")) // DelambdafyTransformer currently only emits generic FunctionN-s, use the old style in the meantime - ) + def canUseDelamdafyMethod = inConstructorFlag == 0 // Avoiding synthesizing code prone to SI-6666, SI-8363 by using old-style lambda translation if (inlineFunctionExpansion || !canUseDelamdafyMethod) { val parents = addSerializable(abstractFunctionForFunctionType(fun.tpe)) val anonClass = fun.symbol.owner newAnonymousFunctionClass(fun.pos, inConstructorFlag) addAnnotation SerialVersionUIDAnnotation @@ -575,6 +573,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 @@ -586,11 +585,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) @@ -684,7 +694,7 @@ abstract class UnCurry extends InfoTransform // declared type and assign this to a synthetic val. Later, we'll patch // the method body to refer to this, rather than the parameter. val tempVal: ValDef = { - // SI-9442: using the "uncurry-erased" type (the one after the uncurry phase) can lead to incorrect + // SI-9442: using the "uncurry-erased" type (the one after the uncurry phase) can lead to incorrect // tree transformations. For example, compiling: // ``` // def foo(c: Ctx)(l: c.Tree): Unit = { @@ -713,7 +723,7 @@ abstract class UnCurry extends InfoTransform // to redo this desugaring manually here // 2. the type needs to be normalized, since `gen.mkCast` checks this (no HK here, just aliases have // to be expanded before handing the type to `gen.mkAttributedCast`, which calls `gen.mkCast`) - val info0 = + val info0 = enteringUncurry(p.symbol.info) match { case DesugaredParameterType(desugaredTpe) => desugaredTpe |