[FIR2IR] Replace star projections with upper bounds for SAM conversion types
This commit is contained in:
+20
-1
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.isKMutableProperty
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
@@ -622,7 +623,8 @@ class CallAndReferenceGenerator(
|
||||
return this
|
||||
}
|
||||
val samFirType = parameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.let {
|
||||
val substituted = substitutor.substituteOrSelf(it)
|
||||
var substituted = substitutor.substituteOrSelf(it)
|
||||
substituted = starProjectionApproximator.substituteOrSelf(substituted)
|
||||
if (substituted is ConeRawType) substituted.lowerBound else substituted
|
||||
}
|
||||
var samType = samFirType?.toIrType(ConversionTypeContext.WITH_INVARIANT) ?: createErrorType()
|
||||
@@ -634,6 +636,23 @@ class CallAndReferenceGenerator(
|
||||
return IrTypeOperatorCallImpl(this.startOffset, this.endOffset, samType, IrTypeOperator.SAM_CONVERSION, samType, this)
|
||||
}
|
||||
|
||||
private val starProjectionApproximator = object : AbstractConeSubstitutor() {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
if (type !is ConeClassLikeType || type.typeArguments.none { it == ConeStarProjection }) return null
|
||||
val fir = type.lookupTag.toSymbol(session)?.fir as? FirTypeParameterRefsOwner ?: return null
|
||||
val typeParameters = fir.typeParameters.map { it.symbol.fir }
|
||||
if (typeParameters.size != type.typeArguments.size) return null
|
||||
val newTypeArguments = typeParameters.zip(type.typeArguments).map { (parameter, argument) ->
|
||||
if (argument == ConeStarProjection){
|
||||
parameter.bounds.first().coneType
|
||||
} else {
|
||||
argument
|
||||
}
|
||||
}
|
||||
return type.withArguments(newTypeArguments.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
private fun needSamConversion(argument: FirExpression, parameter: FirValueParameter): Boolean {
|
||||
// If the type of the argument is already an explicitly subtype of the type of the parameter, we don't need SAM conversion.
|
||||
if (argument.typeRef !is FirResolvedTypeRef ||
|
||||
|
||||
+6
@@ -37440,6 +37440,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/sam/samConstructorGenericSignature.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("samConversionToJavaWildcard.kt")
|
||||
public void testSamConversionToJavaWildcard() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/sam/samConversionToJavaWildcard.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartCastSamConversion.kt")
|
||||
public void testSmartCastSamConversion() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user