IR: fix SAM conversion for types with contravariant intersection argument type
In the added test, the problem was that the SAM type as computed by
`SamTypeFactory.createByValueParameter` was `Consumer<{BaseClass &
BaseInterface}>`, which was latter approximated in psi2ir during the
KotlinType->IrType conversion to `Consumer<out Any?>` (here:
https://github.com/JetBrains/kotlin/blob/3034d9d791cf1f9033104e12448e0d262d3bc3ce/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt#L606),
because intersection type argument is approximated to `out Any?`.
To avoid this, replace intersection type in immediate arguments of a SAM
type with the common supertype of its components at the same place where
we're getting rid of projections.
#KT-45945 Fixed
This commit is contained in:
@@ -9,6 +9,8 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator
|
||||
import org.jetbrains.kotlin.resolve.calls.commonSuperType
|
||||
import org.jetbrains.kotlin.resolve.sam.getAbstractMembers
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithNothing
|
||||
@@ -80,11 +82,19 @@ open class SamTypeFactory {
|
||||
}
|
||||
|
||||
private fun KotlinType.removeExternalProjections(): KotlinType {
|
||||
val newArguments = arguments.map { TypeProjectionImpl(Variance.INVARIANT, it.type) }
|
||||
val newArguments = arguments.map {
|
||||
val type = it.type
|
||||
TypeProjectionImpl(
|
||||
Variance.INVARIANT,
|
||||
if (type.constructor is IntersectionTypeConstructor)
|
||||
NewCommonSuperTypeCalculator.commonSuperType(type.constructor.supertypes.map(KotlinType::unwrap))
|
||||
else type
|
||||
)
|
||||
}
|
||||
return replace(newArguments)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val INSTANCE = SamTypeFactory()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user