FIR2IR: Imitate K1 behavior when SAM type has a bit different shape
See the relevant test at t/
estData/codegen/box/sam/contravariantIntersectionType.kt
After the previous commit, when generating a call for `doOnSuccess {}`,
we have a SAM type with removed projection Consumer<Any?>, while
real function type of the lambda is a bit different
(Function1<ConcreteType & ConcreteType2>).
While for me, that looks questionable, but in K1 it was effectively
resolved via the same implicit cast that on JVM is generated to an
INVOKEDYNAMIC that wraps initial function-typed value.
^KT-53552 Fixed
This commit is contained in:
committed by
Space Team
parent
05ca001310
commit
99448b77f3
+20
-1
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi2ir.generators.implicitCastTo
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.model.TypeVariance
|
||||
@@ -443,7 +444,25 @@ internal class AdapterGenerator(
|
||||
val samType = samFirType.toIrType(ConversionTypeContext.DEFAULT)
|
||||
// Make sure the converted IrType owner indeed has a single abstract method, since FunctionReferenceLowering relies on it.
|
||||
if (!samType.isSamType) return this
|
||||
return IrTypeOperatorCallImpl(this.startOffset, this.endOffset, samType, IrTypeOperator.SAM_CONVERSION, samType, this)
|
||||
return IrTypeOperatorCallImpl(
|
||||
this.startOffset, this.endOffset, samType, IrTypeOperator.SAM_CONVERSION, samType,
|
||||
castArgumentToFunctionalInterfaceForSamType(this, argument.typeRef.coneType, samFirType)
|
||||
)
|
||||
}
|
||||
|
||||
// See org.jetbrains.kotlin.psi2ir.generators.ArgumentsGenerationUtilsKt.castArgumentToFunctionalInterfaceForSamType (K1 counterpart)
|
||||
private fun castArgumentToFunctionalInterfaceForSamType(
|
||||
argument: IrExpression,
|
||||
argumentConeType: ConeKotlinType,
|
||||
samType: ConeKotlinType
|
||||
): IrExpression {
|
||||
val coneKotlinFunctionType = getFunctionTypeForPossibleSamType(samType) ?: return argument
|
||||
// This line is not present in the K1 counterpart because there is InsertImplicitCasts::cast that effectively removes
|
||||
// such unnecessary casts. At the same time, many IR lowerings assume that there are no such redundant casts and many
|
||||
// tests from FirBlackBoxCodegenTestGenerated relevant to INDY start failing once this line is removed.
|
||||
if (argumentConeType.isSubtypeOf(coneKotlinFunctionType, session)) return argument
|
||||
val irFunctionType = coneKotlinFunctionType.toIrType()
|
||||
return argument.implicitCastTo(irFunctionType)
|
||||
}
|
||||
|
||||
// This function is mostly a mirror of org.jetbrains.kotlin.backend.common.SamTypeApproximator.removeExternalProjections
|
||||
|
||||
Reference in New Issue
Block a user