[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.inferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
|
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.isKMutableProperty
|
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.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
@@ -622,7 +623,8 @@ class CallAndReferenceGenerator(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
val samFirType = parameter.returnTypeRef.coneTypeSafe<ConeKotlinType>()?.let {
|
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
|
if (substituted is ConeRawType) substituted.lowerBound else substituted
|
||||||
}
|
}
|
||||||
var samType = samFirType?.toIrType(ConversionTypeContext.WITH_INVARIANT) ?: createErrorType()
|
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)
|
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 {
|
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 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 ||
|
if (argument.typeRef !is FirResolvedTypeRef ||
|
||||||
|
|||||||
+6
@@ -37440,6 +37440,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/sam/samConstructorGenericSignature.kt");
|
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
|
@Test
|
||||||
@TestMetadata("smartCastSamConversion.kt")
|
@TestMetadata("smartCastSamConversion.kt")
|
||||||
public void testSmartCastSamConversion() throws Exception {
|
public void testSmartCastSamConversion() throws Exception {
|
||||||
|
|||||||
Vendored
-1
@@ -1,5 +1,4 @@
|
|||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// JVM_TARGET: 1.8
|
// JVM_TARGET: 1.8
|
||||||
// SAM_CONVERSIONS: INDY
|
// SAM_CONVERSIONS: INDY
|
||||||
fun interface Cmp<T> {
|
fun interface Cmp<T> {
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// FULL_JDK
|
||||||
|
// FILE: ConventionMapping.java
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
public class ConventionMapping {
|
||||||
|
MappedProperty map(String propertyName, Callable<?> value) {
|
||||||
|
return new MappedProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MappedProperty {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: FileCollection.java
|
||||||
|
|
||||||
|
public class FileCollection {}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
fun test(mapping: ConventionMapping, fn: () -> FileCollection) {
|
||||||
|
mapping.map("classpath", fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String = "OK"
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
fun test1() {
|
|
||||||
bar(j = local fun <anonymous>(x: Any): @FlexibleNullability Any? {
|
|
||||||
return x
|
|
||||||
}
|
|
||||||
/*-> @FlexibleNullability J<*>? */)
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
FILE fqName:<root> fileName:/samByProjectedType.kt
|
|
||||||
FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
|
||||||
BLOCK_BODY
|
|
||||||
CALL 'public open fun bar (j: @[FlexibleNullability] <root>.J<*>?): kotlin.Unit declared in <root>.H' type=kotlin.Unit origin=null
|
|
||||||
j: TYPE_OP type=@[FlexibleNullability] <root>.J<*>? origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] <root>.J<*>?
|
|
||||||
FUN_EXPR type=kotlin.Function1<kotlin.Any, @[FlexibleNullability] kotlin.Any?> origin=LAMBDA
|
|
||||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (x:kotlin.Any) returnType:@[FlexibleNullability] kotlin.Any?
|
|
||||||
VALUE_PARAMETER name:x index:0 type:kotlin.Any
|
|
||||||
BLOCK_BODY
|
|
||||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (x: kotlin.Any): @[FlexibleNullability] kotlin.Any? declared in <root>.test1'
|
|
||||||
GET_VAR 'x: kotlin.Any declared in <root>.test1.<anonymous>' type=kotlin.Any origin=null
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// FILE: samByProjectedType.kt
|
// FILE: samByProjectedType.kt
|
||||||
fun test1() {
|
fun test1() {
|
||||||
H.bar { x: Any -> x }
|
H.bar { x: Any -> x }
|
||||||
|
|||||||
+6
@@ -37440,6 +37440,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/sam/samConstructorGenericSignature.kt");
|
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
|
@Test
|
||||||
@TestMetadata("smartCastSamConversion.kt")
|
@TestMetadata("smartCastSamConversion.kt")
|
||||||
public void testSmartCastSamConversion() throws Exception {
|
public void testSmartCastSamConversion() throws Exception {
|
||||||
|
|||||||
+6
@@ -37440,6 +37440,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/sam/samConstructorGenericSignature.kt");
|
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
|
@Test
|
||||||
@TestMetadata("smartCastSamConversion.kt")
|
@TestMetadata("smartCastSamConversion.kt")
|
||||||
public void testSmartCastSamConversion() throws Exception {
|
public void testSmartCastSamConversion() throws Exception {
|
||||||
|
|||||||
+5
@@ -29842,6 +29842,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/sam/samConstructorGenericSignature.kt");
|
runTest("compiler/testData/codegen/box/sam/samConstructorGenericSignature.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("samConversionToJavaWildcard.kt")
|
||||||
|
public void testSamConversionToJavaWildcard() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/sam/samConversionToJavaWildcard.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("smartCastSamConversion.kt")
|
@TestMetadata("smartCastSamConversion.kt")
|
||||||
public void testSmartCastSamConversion() throws Exception {
|
public void testSmartCastSamConversion() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/sam/smartCastSamConversion.kt");
|
runTest("compiler/testData/codegen/box/sam/smartCastSamConversion.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user