Skip to content

Commit 762c910

Browse files
committed
Support specialized method-handle based lambdas
``` scala> (x: Int) => {??? : Int} res2: Int => Int = $$Lambda$1371/1961176822@6ed3ccb2 scala> res2(42) scala.NotImplementedError: an implementation is missing at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225) at .$anonfun$1(<console>:8) at $$Lambda$1371/1961176822.apply$mcII$sp(Unknown Source) ... 33 elided scala> (x: Int, y: Long) => {??? : Int} res4: (Int, Long) => Int = $$Lambda$1382/1796047085@6f8e8894 scala> res4(0, 0L) scala.NotImplementedError: an implementation is missing at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225) at .$anonfun$1(<console>:8) at $$Lambda$1382/1796047085.apply$mcIIJ$sp(Unknown Source) ... 33 elided ```
1 parent 2004d3e commit 762c910

File tree

3 files changed

+27
-7
lines changed

3 files changed

+27
-7
lines changed

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -307,11 +307,16 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
307307
val functionalInterface: Symbol = {
308308
val sym = originalFunction.tpe.typeSymbol
309309
val pack = currentRun.runDefinitions.Scala_Java8_CompatPackage
310-
val returnUnit = restpe.typeSymbol == UnitClass
311-
val functionInterfaceArray =
312-
if (returnUnit) currentRun.runDefinitions.Scala_Java8_CompatPackage_JProcedure
313-
else currentRun.runDefinitions.Scala_Java8_CompatPackage_JFunction
314-
functionInterfaceArray.apply(arity)
310+
val name1 = specializeTypes.specializedFunctionName(sym, originalFunction.tpe.typeArgs)
311+
if (name1.toTypeName == sym.name) {
312+
val returnUnit = restpe.typeSymbol == UnitClass
313+
val functionInterfaceArray =
314+
if (returnUnit) currentRun.runDefinitions.Scala_Java8_CompatPackage_JProcedure
315+
else currentRun.runDefinitions.Scala_Java8_CompatPackage_JFunction
316+
functionInterfaceArray.apply(arity)
317+
} else {
318+
pack.info.decl(name1.toTypeName.prepend("J"))
319+
}
315320
}
316321
if (functionalInterface.exists) {
317322
val targetAttachment = LambdaMetaFactoryCapable(targetMethod(originalFunction), arity, functionalInterface)

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,17 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
303303
}
304304
}
305305

306+
def specializedFunctionName(sym: Symbol, args: List[Type]) = exitingSpecialize {
307+
require(isFunctionSymbol(sym), sym)
308+
val env: TypeEnv = TypeEnv.fromSpecialization(sym, args)
309+
specializedClass.get((sym, env)) match {
310+
case Some(x) =>
311+
x.name
312+
case None =>
313+
sym.name
314+
}
315+
}
316+
306317
/** Return the specialized name of 'sym' in the given environment. It
307318
* guarantees the same result regardless of the map order by sorting
308319
* type variables alphabetically.
@@ -315,10 +326,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
315326
if (sym.isClass) env.keySet
316327
else specializedTypeVars(sym).intersect(env.keySet)
317328
)
329+
specializedName(sym.name, tvars, env)
330+
}
331+
332+
private def specializedName(name: Name, tvars: immutable.Set[Symbol], env: TypeEnv): TermName = {
318333
val (methparams, others) = tvars.toList sortBy ("" + _.name) partition (_.owner.isMethod)
319334
// debuglog("specName(" + sym + ") env: " + env + " tvars: " + tvars)
320335

321-
specializedName(sym.name, methparams map env, others map env)
336+
specializedName(name, methparams map env, others map env)
322337
}
323338

324339
/** Specialize name for the two list of types. The first one denotes

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ abstract class UnCurry extends InfoTransform
237237

238238
def canUseDelamdafyMethod = (
239239
(inConstructorFlag == 0) // Avoiding synthesizing code prone to SI-6666, SI-8363 by using old-style lambda translation
240-
&& !isSpecialized // DelambdafyTransformer currently only emits generic FunctionN-s, use the old style in the meantime
240+
&& (!isSpecialized || (settings.target.value == "jvm-1.8")) // DelambdafyTransformer currently only emits generic FunctionN-s, use the old style in the meantime
241241
)
242242
if (inlineFunctionExpansion || !canUseDelamdafyMethod) {
243243
val parents = addSerializable(abstractFunctionForFunctionType(fun.tpe))

0 commit comments

Comments
 (0)