@@ -1414,7 +1414,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
14141414 def  genLoadTry (tree : Try ):  BType 
14151415
14161416 def  genInvokeDynamicLambda (ctor : Symbol , lambdaTarget : Symbol , environmentSize : Int , functionalInterface : Symbol ):  BType  =  {
1417-  import  java .lang .invoke .LambdaMetafactory .FLAG_SERIALIZABLE 
1417+  import  java .lang .invoke .LambdaMetafactory .{ FLAG_BRIDGES ,  FLAG_SERIALIZABLE } 
14181418
14191419 report.debuglog(s " Using invokedynamic rather than `new  ${ctor.owner}` " )
14201420 val  generatedType  =  classBTypeFromSymbol(functionalInterface)
@@ -1445,9 +1445,9 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
14451445 val  functionalInterfaceDesc :  String  =  generatedType.descriptor
14461446 val  desc  =  capturedParamsTypes.map(tpe =>  toTypeKind(tpe)).mkString((" ("  ), " "  , " )"  ) +  functionalInterfaceDesc
14471447 //  TODO specialization
1448-  val  constrainedType  =  new  MethodBType (lambdaParamTypes.map(p =>  toTypeKind(p)), toTypeKind(lambdaTarget.info.resultType)).toASMType
1448+  val  instantiatedMethodType  =  new  MethodBType (lambdaParamTypes.map(p =>  toTypeKind(p)), toTypeKind(lambdaTarget.info.resultType)).toASMType
14491449
1450-  val  abstractMethod  =  atPhase(erasurePhase) {
1450+  val  samMethod  =  atPhase(erasurePhase) {
14511451 val  samMethods  =  toDenot(functionalInterface).info.possibleSamMethods.toList
14521452 samMethods match  {
14531453 case  x ::  Nil  =>  x.symbol
@@ -1457,21 +1457,40 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
14571457 }
14581458 }
14591459
1460-  val  methodName  =  abstractMethod.javaSimpleName
1461-  val  applyN  =  {
1462-  val  mt  =  asmMethodType(abstractMethod)
1463-  mt.toASMType
1460+  val  methodName  =  samMethod.javaSimpleName
1461+  val  samMethodType  =  asmMethodType(samMethod).toASMType
1462+  //  scala/bug#10334: make sure that a lambda object for `T => U` has a method `apply(T)U`, not only the `(Object)Object`
1463+  //  version. Using the lambda a structural type `{def apply(t: T): U}` causes a reflective lookup for this method.
1464+  val  needsGenericBridge  =  samMethodType !=  instantiatedMethodType
1465+  val  bridgeMethods  =  atPhase(erasurePhase){
1466+  samMethod.allOverriddenSymbols.toList
14641467 }
1465-  val  bsmArgs0  =  Seq (applyN, targetHandle, constrainedType)
1466-  val  bsmArgs  = 
1467-  if  (isSerializable)
1468-  bsmArgs0 :+  Int .box(FLAG_SERIALIZABLE )
1468+  val  overriddenMethodTypes  =  bridgeMethods.map(b =>  asmMethodType(b).toASMType)
1469+ 
1470+  //  any methods which `samMethod` overrides need bridges made for them
1471+  //  this is done automatically during erasure for classes we generate, but LMF needs to have them explicitly mentioned
1472+  //  so we have to compute them at this relatively late point.
1473+  val  bridgeTypes  =  (
1474+  if  (needsGenericBridge)
1475+  instantiatedMethodType +:  overriddenMethodTypes
14691476 else 
1470-  bsmArgs0
1477+  overriddenMethodTypes
1478+  ).distinct.filterNot(_ ==  samMethodType)
1479+ 
1480+  val  needsBridges  =  bridgeTypes.nonEmpty
1481+ 
1482+  def  flagIf (b : Boolean , flag : Int ):  Int  =  if  (b) flag else  0 
1483+  val  flags  =  flagIf(isSerializable, FLAG_SERIALIZABLE ) |  flagIf(needsBridges, FLAG_BRIDGES )
1484+ 
1485+  val  bsmArgs0  =  Seq (samMethodType, targetHandle, instantiatedMethodType)
1486+  val  bsmArgs1  =  if  (flags !=  0 ) Seq (Int .box(flags)) else  Seq .empty
1487+  val  bsmArgs2  =  if  needsBridges then  bridgeTypes.length +:  bridgeTypes else  Seq .empty
1488+ 
1489+  val  bsmArgs  =  bsmArgs0 ++  bsmArgs1 ++  bsmArgs2
14711490
14721491 val  metafactory  = 
1473-  if  (isSerializable )
1474-  lambdaMetaFactoryAltMetafactoryHandle //  altMetafactory needed  to be able to pass the SERIALIZABLE flag 
1492+  if  (flags  !=   0 )
1493+  lambdaMetaFactoryAltMetafactoryHandle //  altMetafactory required  to be able to pass the flags and additional arguments if needed 
14751494 else 
14761495 lambdaMetaFactoryMetafactoryHandle
14771496
0 commit comments