Skip to content

Commit 3567109

Browse files
ddtthhlrytz
authored andcommitted
Ensure dynamicMethodType in IndyLambda adhere to the specification
Box native instantiated method return type if sam method return type is not a primitive type to satisfy conditions specified in https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/LambdaMetafactory.html Condition is not enforced by JVM but by Android ART. Fixes scala#15736
1 parent fe982db commit 3567109

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,8 +1773,6 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
17731773
val returnUnit = lambdaTarget.info.resultType.typeSymbol == defn.UnitClass
17741774
val functionalInterfaceDesc: String = generatedType.descriptor
17751775
val desc = capturedParamsTypes.map(tpe => toTypeKind(tpe)).mkString(("("), "", ")") + functionalInterfaceDesc
1776-
// TODO specialization
1777-
val instantiatedMethodType = new MethodBType(lambdaParamTypes.map(p => toTypeKind(p)), toTypeKind(lambdaTarget.info.resultType)).toASMType
17781776

17791777
val samMethod = atPhase(erasurePhase) {
17801778
val samMethods = toDenot(functionalInterface).info.possibleSamMethods.toList
@@ -1787,7 +1785,21 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
17871785
}
17881786

17891787
val methodName = samMethod.javaSimpleName
1790-
val samMethodType = asmMethodType(samMethod).toASMType
1788+
val samMethodBType = asmMethodType(samMethod)
1789+
val samMethodType = samMethodBType.toASMType
1790+
1791+
def boxInstantiated(instantiatedType: BType, samType: BType): BType =
1792+
if(!samType.isPrimitive && instantiatedType.isPrimitive)
1793+
boxedClassOfPrimitive(instantiatedType.asPrimitiveBType)
1794+
else instantiatedType
1795+
// TODO specialization
1796+
val instantiatedMethodBType = new MethodBType(
1797+
lambdaParamTypes.map(p => toTypeKind(p)),
1798+
boxInstantiated(toTypeKind(lambdaTarget.info.resultType), samMethodBType.returnType)
1799+
)
1800+
1801+
val instantiatedMethodType = instantiatedMethodBType.toASMType
1802+
17911803
// scala/bug#10334: make sure that a lambda object for `T => U` has a method `apply(T)U`, not only the `(Object)Object`
17921804
// version. Using the lambda a structural type `{def apply(t: T): U}` causes a reflective lookup for this method.
17931805
val needsGenericBridge = samMethodType != instantiatedMethodType

0 commit comments

Comments
 (0)