FIR2IR: use invariant projections for SAM_CONVERSION types
This commit is contained in:
@@ -71,16 +71,32 @@ internal enum class ConversionTypeOrigin {
|
||||
|
||||
class ConversionTypeContext internal constructor(
|
||||
internal val definitelyNotNull: Boolean,
|
||||
internal val origin: ConversionTypeOrigin
|
||||
internal val invariantProjection: Boolean = false,
|
||||
internal val origin: ConversionTypeOrigin = ConversionTypeOrigin.DEFAULT,
|
||||
) {
|
||||
fun definitelyNotNull() = ConversionTypeContext(true, origin)
|
||||
fun definitelyNotNull() = ConversionTypeContext(
|
||||
definitelyNotNull = true,
|
||||
invariantProjection = invariantProjection,
|
||||
origin = origin
|
||||
)
|
||||
|
||||
fun inSetter() = ConversionTypeContext(definitelyNotNull, ConversionTypeOrigin.SETTER)
|
||||
fun inSetter() = ConversionTypeContext(
|
||||
definitelyNotNull = definitelyNotNull,
|
||||
invariantProjection = invariantProjection,
|
||||
origin = ConversionTypeOrigin.SETTER
|
||||
)
|
||||
|
||||
fun withInvariantProjections() = ConversionTypeContext(
|
||||
definitelyNotNull = definitelyNotNull,
|
||||
invariantProjection = true,
|
||||
origin = origin
|
||||
)
|
||||
|
||||
companion object {
|
||||
internal val DEFAULT = ConversionTypeContext(
|
||||
definitelyNotNull = false, origin = ConversionTypeOrigin.DEFAULT
|
||||
definitelyNotNull = false, origin = ConversionTypeOrigin.DEFAULT, invariantProjection = false
|
||||
)
|
||||
internal val WITH_INVARIANT = DEFAULT.withInvariantProjections()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.fir.expressions.classId
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
@@ -20,7 +19,6 @@ import org.jetbrains.kotlin.ir.types.IrTypeArgument
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
@@ -150,11 +148,11 @@ class Fir2IrTypeConverter(
|
||||
ConeStarProjection -> IrStarProjectionImpl
|
||||
is ConeKotlinTypeProjectionIn -> {
|
||||
val irType = this.type.toIrType(typeContext)
|
||||
makeTypeProjection(irType, Variance.IN_VARIANCE)
|
||||
makeTypeProjection(irType, if (typeContext.invariantProjection) Variance.INVARIANT else Variance.IN_VARIANCE)
|
||||
}
|
||||
is ConeKotlinTypeProjectionOut -> {
|
||||
val irType = this.type.toIrType(typeContext)
|
||||
makeTypeProjection(irType, Variance.OUT_VARIANCE)
|
||||
makeTypeProjection(irType, if (typeContext.invariantProjection) Variance.INVARIANT else Variance.OUT_VARIANCE)
|
||||
}
|
||||
is ConeKotlinType -> {
|
||||
if (this is ConeCapturedType && this in capturedTypeCache && this.isRecursive(mutableSetOf())) {
|
||||
|
||||
+3
-2
@@ -52,7 +52,8 @@ class CallAndReferenceGenerator(
|
||||
private val adapterGenerator = AdapterGenerator(components, conversionScope)
|
||||
private val samResolver = FirSamResolverImpl(session, scopeSession)
|
||||
|
||||
private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() }
|
||||
private fun FirTypeRef.toIrType(conversionTypeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType =
|
||||
with(typeConverter) { toIrType(conversionTypeContext) }
|
||||
|
||||
private fun ConeKotlinType.toIrType(): IrType = with(typeConverter) { toIrType() }
|
||||
|
||||
@@ -608,7 +609,7 @@ class CallAndReferenceGenerator(
|
||||
if (!needSamConversion(argument, parameter)) {
|
||||
return this
|
||||
}
|
||||
var samType = parameter.returnTypeRef.toIrType()
|
||||
var samType = parameter.returnTypeRef.toIrType(ConversionTypeContext.WITH_INVARIANT)
|
||||
if (shouldUnwrapVarargType) {
|
||||
samType = samType.getArrayElementType(irBuiltIns)
|
||||
}
|
||||
|
||||
Generated
+6
@@ -2152,6 +2152,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
runTest("compiler/testData/ir/irText/firProblems/JCTree.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt19251.kt")
|
||||
public void testKt19251() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/firProblems/kt19251.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt43342.kt")
|
||||
public void testKt43342() throws Exception {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// JVM_TARGET: 1.8
|
||||
// SAM_CONVERSIONS: INDY
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// JVM_TARGET: 1.8
|
||||
// SAM_CONVERSIONS: INDY
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// DONT_TARGET_EXACT_BACKEND: JS JS_IR JS_IR_ES6 WASM NATIVE
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// SKIP_JDK6
|
||||
// MODULE: lib
|
||||
// FILE: Custom.java
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// JVM_TARGET: 1.8
|
||||
// SAM_CONVERSIONS: INDY
|
||||
// WITH_RUNTIME
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fun box(): String {
|
||||
val map: MutableMap<Fun, String> = mutableMapOf<Fun, String>()
|
||||
val fn: Fun = local fun <anonymous>(it: String?): String? {
|
||||
return TODO()
|
||||
}
|
||||
/*-> Fun */
|
||||
return map.computeIfAbsent(p0 = fn, p1 = local fun <anonymous>(it: Fun?): String? {
|
||||
return "OK"
|
||||
}
|
||||
/*-> @FlexibleNullability Function<Fun?, String?> */)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
FILE fqName:<root> fileName:/test.kt
|
||||
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||
BLOCK_BODY
|
||||
VAR name:map type:kotlin.collections.MutableMap<<root>.Fun, kotlin.String> [val]
|
||||
CALL 'public final fun mutableMapOf <K, V> (): kotlin.collections.MutableMap<K of kotlin.collections.MapsKt.mutableMapOf, V of kotlin.collections.MapsKt.mutableMapOf> [inline] declared in kotlin.collections.MapsKt' type=kotlin.collections.MutableMap<<root>.Fun, kotlin.String> origin=null
|
||||
<K>: <root>.Fun
|
||||
<V>: kotlin.String
|
||||
VAR name:fn type:<root>.Fun [val]
|
||||
TYPE_OP type=<root>.Fun origin=SAM_CONVERSION typeOperand=<root>.Fun
|
||||
FUN_EXPR type=kotlin.Function1<kotlin.String?, kotlin.String?> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:kotlin.String?) returnType:kotlin.String?
|
||||
VALUE_PARAMETER name:it index:0 type:kotlin.String?
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (it: kotlin.String?): kotlin.String? declared in <root>.box'
|
||||
CALL 'public final fun TODO (): kotlin.Nothing [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
|
||||
CALL 'public open fun computeIfAbsent (p0: K of kotlin.collections.MutableMap, p1: @[FlexibleNullability] java.util.function.Function<in K of kotlin.collections.MutableMap?, out V of kotlin.collections.MutableMap?>): V of kotlin.collections.MutableMap declared in kotlin.collections.MutableMap' type=kotlin.String origin=null
|
||||
$this: GET_VAR 'val map: kotlin.collections.MutableMap<<root>.Fun, kotlin.String> [val] declared in <root>.box' type=kotlin.collections.MutableMap<<root>.Fun, kotlin.String> origin=null
|
||||
p0: GET_VAR 'val fn: <root>.Fun [val] declared in <root>.box' type=<root>.Fun origin=null
|
||||
p1: TYPE_OP type=@[FlexibleNullability] java.util.function.Function<<root>.Fun?, kotlin.String?> origin=SAM_CONVERSION typeOperand=@[FlexibleNullability] java.util.function.Function<<root>.Fun?, kotlin.String?>
|
||||
FUN_EXPR type=kotlin.Function1<<root>.Fun?, kotlin.String?> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:<root>.Fun?) returnType:kotlin.String?
|
||||
VALUE_PARAMETER name:it index:0 type:<root>.Fun?
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (it: <root>.Fun?): kotlin.String? declared in <root>.box'
|
||||
CONST String type=kotlin.String value="OK"
|
||||
@@ -0,0 +1,14 @@
|
||||
// WITH_RUNTIME
|
||||
// FULL_JDK
|
||||
// FILE: Fun.java
|
||||
public interface Fun {
|
||||
String invoke(String string);
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
fun box(): String {
|
||||
val map = mutableMapOf<Fun, String>()
|
||||
val fn = Fun { TODO() }
|
||||
return map.computeIfAbsent(fn, { "OK" })
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fun box(): String {
|
||||
val map: MutableMap<Fun, String> = mutableMapOf<Fun, String>()
|
||||
val fn: Fun = local fun <anonymous>(it: @FlexibleNullability String?): @FlexibleNullability String? {
|
||||
TODO()
|
||||
}
|
||||
/*-> Fun */
|
||||
return map.computeIfAbsent(p0 = fn, p1 = local fun <anonymous>(it: @EnhancedNullability Fun): @EnhancedNullability String {
|
||||
return "OK"
|
||||
}
|
||||
/*-> @EnhancedNullability Function<@EnhancedNullability Fun, @EnhancedNullability String> */) /*!! String */
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
FILE fqName:<root> fileName:/test.kt
|
||||
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||
BLOCK_BODY
|
||||
VAR name:map type:kotlin.collections.MutableMap<<root>.Fun, kotlin.String> [val]
|
||||
CALL 'public final fun mutableMapOf <K, V> (): kotlin.collections.MutableMap<K of kotlin.collections.MapsKt.mutableMapOf, V of kotlin.collections.MapsKt.mutableMapOf> [inline] declared in kotlin.collections.MapsKt' type=kotlin.collections.MutableMap<<root>.Fun, kotlin.String> origin=null
|
||||
<K>: <root>.Fun
|
||||
<V>: kotlin.String
|
||||
VAR name:fn type:<root>.Fun [val]
|
||||
TYPE_OP type=<root>.Fun origin=SAM_CONVERSION typeOperand=<root>.Fun
|
||||
FUN_EXPR type=kotlin.Function1<@[ParameterName(name = 'string')] @[FlexibleNullability] kotlin.String?, @[FlexibleNullability] kotlin.String?> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:@[FlexibleNullability] kotlin.String?) returnType:@[FlexibleNullability] kotlin.String?
|
||||
VALUE_PARAMETER name:it index:0 type:@[FlexibleNullability] kotlin.String?
|
||||
BLOCK_BODY
|
||||
CALL 'public final fun TODO (): kotlin.Nothing [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
|
||||
TYPE_OP type=kotlin.String origin=IMPLICIT_NOTNULL typeOperand=kotlin.String
|
||||
CALL 'public open fun computeIfAbsent (p0: @[EnhancedNullability] K of kotlin.collections.MutableMap, p1: @[EnhancedNullability] java.util.function.Function<in @[EnhancedNullability] K of kotlin.collections.MutableMap, out @[EnhancedNullability] V of kotlin.collections.MutableMap>): @[EnhancedNullability] V of kotlin.collections.MutableMap declared in kotlin.collections.MutableMap' type=@[EnhancedNullability] kotlin.String origin=null
|
||||
$this: GET_VAR 'val map: kotlin.collections.MutableMap<<root>.Fun, kotlin.String> [val] declared in <root>.box' type=kotlin.collections.MutableMap<<root>.Fun, kotlin.String> origin=null
|
||||
p0: GET_VAR 'val fn: <root>.Fun [val] declared in <root>.box' type=<root>.Fun origin=null
|
||||
p1: TYPE_OP type=@[EnhancedNullability] java.util.function.Function<@[EnhancedNullability] <root>.Fun, @[EnhancedNullability] kotlin.String> origin=SAM_CONVERSION typeOperand=@[EnhancedNullability] java.util.function.Function<@[EnhancedNullability] <root>.Fun, @[EnhancedNullability] kotlin.String>
|
||||
FUN_EXPR type=kotlin.Function1<@[EnhancedNullability] <root>.Fun, @[EnhancedNullability] kotlin.String> origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> (it:@[EnhancedNullability] <root>.Fun) returnType:@[EnhancedNullability] kotlin.String
|
||||
VALUE_PARAMETER name:it index:0 type:@[EnhancedNullability] <root>.Fun
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (it: @[EnhancedNullability] <root>.Fun): @[EnhancedNullability] kotlin.String declared in <root>.box'
|
||||
CONST String type=kotlin.String value="OK"
|
||||
Generated
+6
@@ -2152,6 +2152,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest {
|
||||
runTest("compiler/testData/ir/irText/firProblems/JCTree.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt19251.kt")
|
||||
public void testKt19251() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/firProblems/kt19251.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt43342.kt")
|
||||
public void testKt43342() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user