Skip to content

Commit d12d59a

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 e1895d6 commit d12d59a

File tree

3 files changed

+27
-7
lines changed

3 files changed

+27
-7
lines changed

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

+10-5
Original file line numberDiff line numberDiff line change
@@ -308,11 +308,16 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
308308
val functionalInterface: Symbol = {
309309
val sym = originalFunction.tpe.typeSymbol
310310
val pack = currentRun.runDefinitions.Scala_Java8_CompatPackage
311-
val returnUnit = restpe.typeSymbol == UnitClass
312-
val functionInterfaceArray =
313-
if (returnUnit) currentRun.runDefinitions.Scala_Java8_CompatPackage_JProcedure
314-
else currentRun.runDefinitions.Scala_Java8_CompatPackage_JFunction
315-
functionInterfaceArray.apply(arity)
311+
val name1 = specializeTypes.specializedFunctionName(sym, originalFunction.tpe.typeArgs)
312+
if (name1.toTypeName == sym.name) {
313+
val returnUnit = restpe.typeSymbol == UnitClass
314+
val functionInterfaceArray =
315+
if (returnUnit) currentRun.runDefinitions.Scala_Java8_CompatPackage_JProcedure
316+
else currentRun.runDefinitions.Scala_Java8_CompatPackage_JFunction
317+
functionInterfaceArray.apply(arity)
318+
} else {
319+
pack.info.decl(name1.toTypeName.prepend("J"))
320+
}
316321
}
317322
if (functionalInterface.exists) {
318323
val captureArgs = captures.iterator.map(capture => gen.mkAttributedRef(capture) setPos originalFunction.pos).toList

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

+16-1
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

+1-1
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)