From d1ba69044e024407fd53d5b02f02eb411c18916d Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Mon, 14 Sep 2020 11:51:05 -0700 Subject: [PATCH] FIR: update the type of anonymous function as SAM --- ...rCallCompletionResultsWriterTransformer.kt | 24 ++++++++++++++++++- .../featureIntersection/funInterface.kt | 1 - 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt index e05e7e2df44..d4629c07fd9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic @@ -17,6 +18,8 @@ import org.jetbrains.kotlin.fir.resolve.calls.FirErrorReferenceWithCandidate import org.jetbrains.kotlin.fir.resolve.calls.FirNamedReferenceWithCandidate import org.jetbrains.kotlin.fir.resolve.calls.varargElementType import org.jetbrains.kotlin.fir.resolve.constructFunctionalTypeRef +import org.jetbrains.kotlin.fir.resolve.createFunctionalType +import org.jetbrains.kotlin.fir.resolve.firProvider import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType @@ -436,7 +439,26 @@ class FirCallCompletionResultsWriterTransformer( anonymousFunction: FirAnonymousFunction, data: ExpectedArgumentType?, ): CompositeTransformResult { - val expectedType = data?.getExpectedType(anonymousFunction)?.takeIf { it.isBuiltinFunctionalType(session) } + val expectedType = data?.getExpectedType(anonymousFunction)?.let { expectedArgumentType -> + // From the argument mapping, the expected type of this anonymous function would be: + when { + // a built-in functional type, no-brainer + expectedArgumentType.isBuiltinFunctionalType(session) -> expectedArgumentType + // fun interface (a.k.a. SAM), then unwrap it and build a functional type from that interface function + expectedArgumentType is ConeClassLikeType -> { + val sam = + (session.firProvider.getFirClassifierByFqName(expectedArgumentType.lookupTag.classId) as? FirClass) + ?.takeIf { it.classKind == ClassKind.INTERFACE } + ?.declarations?.singleOrNull() as? FirSimpleFunction + sam?.let { + createFunctionalType( + sam.valueParameters.map { it.returnTypeRef.coneType }, null, sam.returnTypeRef.coneType, sam.isSuspend + ) + } + } + else -> null + } + } var needUpdateLambdaType = false diff --git a/compiler/testData/codegen/box/coroutines/featureIntersection/funInterface.kt b/compiler/testData/codegen/box/coroutines/featureIntersection/funInterface.kt index d89343f8df1..678f8efa7bb 100644 --- a/compiler/testData/codegen/box/coroutines/featureIntersection/funInterface.kt +++ b/compiler/testData/codegen/box/coroutines/featureIntersection/funInterface.kt @@ -2,7 +2,6 @@ // WITH_COROUTINES // TARGET_BACKEND: JVM // IGNORE_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR import helpers.* import kotlin.coroutines.*