提交 7050af9b 编写于 作者: M Mikhail Glukhikh

FIR2IR: use invariant projections for SAM_CONVERSION types

上级 67671afa
......@@ -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 inSetter() = ConversionTypeContext(definitelyNotNull, ConversionTypeOrigin.SETTER)
fun definitelyNotNull() = ConversionTypeContext(
definitelyNotNull = true,
invariantProjection = invariantProjection,
origin = origin
)
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())) {
......
......@@ -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)
}
......
......@@ -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 {
......
// TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// WITH_RUNTIME
......
// TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// WITH_RUNTIME
......
// DONT_TARGET_EXACT_BACKEND: JS JS_IR JS_IR_ES6 WASM NATIVE
// IGNORE_BACKEND_FIR: JVM_IR
// SKIP_JDK6
// MODULE: lib
// FILE: Custom.java
......
// TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR
// JVM_TARGET: 1.8
// SAM_CONVERSIONS: INDY
// WITH_RUNTIME
......
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?> */)
}
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"
// 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" })
}
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 */
}
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"
......@@ -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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册