From dbc564e74ecdeb6386bbf7bbbd1b8eb500b9daed Mon Sep 17 00:00:00 2001 From: "simon.ogorodnik" Date: Wed, 20 May 2020 20:21:00 +0300 Subject: [PATCH] [FIR2IR] Approximate types for lambdas before passing to serialization --- .../fir/backend/jvm/FirJvmClassCodegen.kt | 38 +++++++++++++++++-- .../builder/FirValueParameterBuilder.kt | 21 ++++++++++ .../fir/tree/generator/BuilderConfigurator.kt | 1 + .../diagnostics/functions/inference/kt6176.kt | 1 - 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmClassCodegen.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmClassCodegen.kt index ea1523090c8..f07141b2acc 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmClassCodegen.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmClassCodegen.kt @@ -21,9 +21,15 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.FirTypeParameter -import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunction +import org.jetbrains.kotlin.fir.declarations.builder.* +import org.jetbrains.kotlin.fir.inferenceContext +import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType import org.jetbrains.kotlin.fir.serialization.FirElementSerializer import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol +import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.fir.types.coneTypeUnsafe import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.declarations.IrFunction @@ -32,6 +38,9 @@ import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable +import org.jetbrains.kotlin.types.AbstractTypeApproximator +import org.jetbrains.kotlin.types.TypeApproximatorConfiguration +import org.jetbrains.kotlin.types.model.SimpleTypeMarker import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.Method @@ -52,16 +61,37 @@ class FirJvmClassCodegen( else -> null } + private val approximator = object : AbstractTypeApproximator(session.inferenceContext) { + override fun createErrorType(message: String): SimpleTypeMarker { + return ConeKotlinErrorType(message) + } + } + + private fun FirTypeRef.approximated( + toSuper: Boolean, + conf: TypeApproximatorConfiguration = TypeApproximatorConfiguration.PublicDeclaration + ): FirTypeRef { + val approximatedType = if (toSuper) + approximator.approximateToSuperType(this.coneTypeUnsafe(), conf) + else + approximator.approximateToSubType(this.coneTypeUnsafe(), conf) + return withReplacedConeType(approximatedType as? ConeKotlinType) + } + private fun FirFunction<*>.copyToFreeAnonymousFunction(): FirAnonymousFunction { val function = this return buildAnonymousFunction { session = function.session origin = FirDeclarationOrigin.Source symbol = FirAnonymousFunctionSymbol() - returnTypeRef = function.returnTypeRef - receiverTypeRef = function.receiverTypeRef + returnTypeRef = function.returnTypeRef.approximated(toSuper = true) + receiverTypeRef = function.receiverTypeRef?.approximated(toSuper = false) isLambda = (function as? FirAnonymousFunction)?.isLambda == true - valueParameters.addAll(function.valueParameters) + valueParameters.addAll(function.valueParameters.map { + buildValueParameterCopy(it) { + returnTypeRef = it.returnTypeRef.approximated(toSuper = false) + } + }) typeParameters.addAll(function.typeParameters.filterIsInstance()) } } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirValueParameterBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirValueParameterBuilder.kt index 6151b420d94..89afbd2a39f 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirValueParameterBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirValueParameterBuilder.kt @@ -72,3 +72,24 @@ inline fun buildValueParameter(init: FirValueParameterBuilder.() -> Unit): FirVa } return FirValueParameterBuilder().apply(init).build() } + +@OptIn(ExperimentalContracts::class) +inline fun buildValueParameterCopy(original: FirValueParameter, init: FirValueParameterBuilder.() -> Unit): FirValueParameter { + contract { + callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE) + } + val copyBuilder = FirValueParameterBuilder() + copyBuilder.source = original.source + copyBuilder.session = original.session + copyBuilder.resolvePhase = original.resolvePhase + copyBuilder.origin = original.origin + copyBuilder.returnTypeRef = original.returnTypeRef + copyBuilder.name = original.name + copyBuilder.symbol = original.symbol + copyBuilder.annotations.addAll(original.annotations) + copyBuilder.defaultValue = original.defaultValue + copyBuilder.isCrossinline = original.isCrossinline + copyBuilder.isNoinline = original.isNoinline + copyBuilder.isVararg = original.isVararg + return copyBuilder.apply(init).build() +} diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt index f2dfc650eba..55d3a7fc2b8 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt @@ -245,6 +245,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator(FirTree builder(valueParameter, type = "FirValueParameterImpl") { openBuilder() + withCopy() } builder(valueParameter, type = "FirDefaultSetterValueParameter") { diff --git a/compiler/testData/codegen/box/diagnostics/functions/inference/kt6176.kt b/compiler/testData/codegen/box/diagnostics/functions/inference/kt6176.kt index 48e4e8d2375..15a7a2e94e2 100644 --- a/compiler/testData/codegen/box/diagnostics/functions/inference/kt6176.kt +++ b/compiler/testData/codegen/box/diagnostics/functions/inference/kt6176.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST fun foo(f: () -> R): R = f()