From 8bdc4d34f72a6b32b1a0618b748a422cd19c2208 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Fri, 15 May 2020 15:27:37 +0300 Subject: [PATCH] [NI] Commonize type-conversions (SAM/Suspend) - Allow participating subtypes of functional types in conversions - Fix several subtle inconsistencies - Place logic about conversions at one place Now conversions operations have two stages: before usual subtyping check and after one. This is needed to support conversions of subtypes (of functional types, for example). First, the compiler checks if it possible to resolve an argument without conversion and only then it tries to perform conversion. Note that it'd be incorrect to perform conversion eagerly as it can change resolve (Runnable & () -> Unit <: KRunnable), plus we can't guess whether conversion is needed at all as it's important not to look into supertypes if resolution doesn't actually needed it #KT-36448 Fixed #KT-37574 Fixed #KT-38604 Fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 5 + .../ir/FirBlackBoxCodegenTestGenerated.java | 25 ++++ .../calls/components/ResolutionParts.kt | 92 +++++++++++---- .../calls/components/samConversionUtils.kt | 102 ++++++++--------- .../components/suspendConversionUtils.kt | 57 +++++----- .../calls/components/typeConversions.kt | 107 ++++++++++++++++++ .../annotatedLambda/samFunReference.kt | 2 - .../intersectionTypeToSubtypeConversion.kt | 39 +++++++ ...typeOfFunctionalTypeToSuspendConversion.kt | 39 +++++++ ...ntersectionTypeToFunInterfaceConversion.kt | 39 +++++++ ...fFunctionalTypeToFunInterfaceConversion.kt | 23 ++++ .../javaInterop/samUnboundTypeParameter.kt | 1 - .../sam/passSubtypeOfFunctionSamConversion.kt | 40 +++++++ .../samConversionsWithSmartCasts.kt | 2 +- .../suspendConversionOnVarargElements.fir.kt | 20 ++++ .../suspendConversionOnVarargElements.kt | 20 ++++ .../suspendConversionOnVarargElements.txt | 5 + .../checkers/DiagnosticsTestGenerated.java | 5 + .../DiagnosticsUsingJavacTestGenerated.java | 5 + .../codegen/BlackBoxCodegenTestGenerated.java | 25 ++++ .../LightAnalysisModeTestGenerated.java | 25 ++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 25 ++++ .../IrJsCodegenBoxTestGenerated.java | 20 ++++ .../semantics/JsCodegenBoxTestGenerated.java | 20 ++++ 24 files changed, 636 insertions(+), 107 deletions(-) create mode 100644 compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/typeConversions.kt create mode 100644 compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt create mode 100644 compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt create mode 100644 compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt create mode 100644 compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt create mode 100644 compiler/testData/codegen/box/sam/passSubtypeOfFunctionSamConversion.kt create mode 100644 compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.fir.kt create mode 100644 compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.kt create mode 100644 compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.txt diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index 085d7462dbf..531310ae261 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -23167,6 +23167,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.kt"); } + @TestMetadata("suspendConversionOnVarargElements.kt") + public void testSuspendConversionOnVarargElements() throws Exception { + runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.kt"); + } + @TestMetadata("suspendConversionWithFunInterfaces.kt") public void testSuspendConversionWithFunInterfaces() throws Exception { runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt"); diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 78a146fe9b7..f4d69fff08a 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -7869,10 +7869,20 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendConversion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @TestMetadata("intersectionTypeToSubtypeConversion.kt") + public void testIntersectionTypeToSubtypeConversion() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt"); + } + @TestMetadata("onArgument.kt") public void testOnArgument() throws Exception { runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt"); } + + @TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt") + public void testSubtypeOfFunctionalTypeToSuspendConversion() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt"); + } } @TestMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine") @@ -11170,6 +11180,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/funInterface/inlinedSamWrapper.kt"); } + @TestMetadata("intersectionTypeToFunInterfaceConversion.kt") + public void testIntersectionTypeToFunInterfaceConversion() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt"); + } + @TestMetadata("multimodule.kt") public void testMultimodule() throws Exception { runTest("compiler/testData/codegen/box/funInterface/multimodule.kt"); @@ -11200,6 +11215,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/funInterface/samConstructorExplicitInvocation.kt"); } + @TestMetadata("subtypeOfFunctionalTypeToFunInterfaceConversion.kt") + public void testSubtypeOfFunctionalTypeToFunInterfaceConversion() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt"); + } + @TestMetadata("suspendFunInterfaceConversionCodegen.kt") public void testSuspendFunInterfaceConversionCodegen() throws Exception { runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt"); @@ -28073,6 +28093,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/sam/partialSamKT.kt"); } + @TestMetadata("passSubtypeOfFunctionSamConversion.kt") + public void testPassSubtypeOfFunctionSamConversion() throws Exception { + runTest("compiler/testData/codegen/box/sam/passSubtypeOfFunctionSamConversion.kt"); + } + @TestMetadata("predicateSamWrapper.kt") public void testPredicateSamWrapper() throws Exception { runTest("compiler/testData/codegen/box/sam/predicateSamWrapper.kt"); diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index a09db6c4a3d..712109b18e6 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -413,7 +413,21 @@ private fun KotlinResolutionCandidate.resolveKotlinArgument( candidateParameter: ParameterDescriptor?, receiverInfo: ReceiverInfo ) { - val expectedType = candidateParameter?.let { prepareExpectedType(argument, candidateParameter) } + val candidateExpectedType = candidateParameter?.let { argument.getExpectedType(it, callComponents.languageVersionSettings) } + + val conversionDataBeforeSubtyping = + if (candidateParameter == null || candidateExpectedType == null) { + null + } else { + TypeConversions.performCompositeConversionBeforeSubtyping( + this, argument, candidateParameter, candidateExpectedType + ) + } + + val convertedExpectedType = conversionDataBeforeSubtyping?.convertedType + val unsubstitutedExpectedType = conversionDataBeforeSubtyping?.convertedType ?: candidateExpectedType + val expectedType = unsubstitutedExpectedType?.let { prepareExpectedType(it) } + val convertedArgument = if (expectedType != null && shouldRunConversionForConstants(expectedType)) { val convertedConstant = resolutionCallbacks.convertSignedConstantToUnsigned(argument) if (convertedConstant != null) { @@ -423,8 +437,14 @@ private fun KotlinResolutionCandidate.resolveKotlinArgument( convertedConstant } else null - addResolvedKtPrimitive( - resolveKtPrimitive( + + if (candidateExpectedType == null || // Nothing to convert + convertedExpectedType != null || // Type is already converted + conversionDataBeforeSubtyping?.wasConversion == true || // We tried to convert type but failed + conversionDataBeforeSubtyping?.conversionDefinitelyNotNeeded == true || + csBuilder.hasContradiction + ) { + val resolvedAtom = resolveKtPrimitive( csBuilder, argument, expectedType, @@ -432,7 +452,54 @@ private fun KotlinResolutionCandidate.resolveKotlinArgument( receiverInfo, convertedArgument?.unknownIntegerType?.unwrap() ) - ) + + addResolvedKtPrimitive(resolvedAtom) + } else { + var convertedTypeAfterSubtyping: UnwrappedType? = null + csBuilder.runTransaction { + val resolvedAtom = resolveKtPrimitive( + csBuilder, + argument, + expectedType, + this@resolveKotlinArgument, + receiverInfo, + convertedArgument?.unknownIntegerType?.unwrap() + ) + + if (!hasContradiction) { + addResolvedKtPrimitive(resolvedAtom) + return@runTransaction true + } + + convertedTypeAfterSubtyping = + TypeConversions.performCompositeConversionAfterSubtyping( + this@resolveKotlinArgument, + argument, + candidateParameter, + candidateExpectedType + )?.let { prepareExpectedType(it) } + + if (convertedTypeAfterSubtyping == null) { + addResolvedKtPrimitive(resolvedAtom) + return@runTransaction true + } + + false + } + + if (convertedTypeAfterSubtyping != null) { + val resolvedAtom = resolveKtPrimitive( + csBuilder, + argument, + convertedTypeAfterSubtyping, + this@resolveKotlinArgument, + receiverInfo, + convertedArgument?.unknownIntegerType?.unwrap() + ) + addResolvedKtPrimitive(resolvedAtom) + } + + } } private fun KotlinResolutionCandidate.shouldRunConversionForConstants(expectedType: UnwrappedType): Boolean { @@ -474,23 +541,6 @@ private fun KotlinResolutionCandidate.checkUnsafeImplicitInvokeAfterSafeCall(arg return ImplicitInvokeCheckStatus.INVOKE_ON_NOT_NULL_VARIABLE } -private fun KotlinResolutionCandidate.prepareExpectedType( - argument: KotlinCallArgument, - parameter: ParameterDescriptor -): UnwrappedType { - val expectedType = - performExpectedTypeConversion(argument, parameter) - ?: argument.getExpectedType(parameter, callComponents.languageVersionSettings) - return prepareExpectedType(expectedType) -} - -private fun KotlinResolutionCandidate.performExpectedTypeConversion( - argument: KotlinCallArgument, - parameter: ParameterDescriptor -): UnwrappedType? { - return getExpectedTypeWithSAMConversion(argument, parameter) ?: getExpectedTypeWithSuspendConversion(argument, parameter) -} - private fun KotlinResolutionCandidate.prepareExpectedType(expectedType: UnwrappedType): UnwrappedType { val resultType = knownTypeParametersResultingSubstitutor?.substitute(expectedType) ?: expectedType return resolvedCall.freshVariablesSubstitutor.safeSubstitute(resultType) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/samConversionUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/samConversionUtils.kt index 3cf482e2bff..01c9d4c7032 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/samConversionUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/samConversionUtils.kt @@ -17,23 +17,11 @@ import org.jetbrains.kotlin.resolve.sam.getFunctionTypeForPossibleSamType import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.typeUtil.isNothing -object SamTypeConversions { - fun conversionMightBeNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean { - return when (argument) { - is SimpleKotlinCallArgument -> argument.receiver.stableType.isFunctionType - is LambdaKotlinCallArgument, is CallableReferenceKotlinCallArgument -> true - else -> false - } - } - - fun conversionMightBeNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean { - return argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionTypeOrSubtype - } - - - fun conversionDefinitelyNotNeeded( +object SamTypeConversions : ParameterTypeConversion { + override fun conversionDefinitelyNotNeeded( candidate: KotlinResolutionCandidate, - candidateParameter: ParameterDescriptor + argument: KotlinCallArgument, + expectedParameterType: UnwrappedType ): Boolean { val callComponents = candidate.callComponents val generatingAdditionalSamCandidateIsEnabled = @@ -41,7 +29,7 @@ object SamTypeConversions { !callComponents.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitVarargAsArrayAfterSamArgument) if (generatingAdditionalSamCandidateIsEnabled) return true - if (candidateParameter.type.isNothing()) return true + if (expectedParameterType.isNothing()) return true val samConversionOracle = callComponents.samConversionOracle if (!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SamConversionForKotlinFunctions)) { @@ -50,48 +38,56 @@ object SamTypeConversions { return false } -} -fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion( - argument: KotlinCallArgument, - candidateParameter: ParameterDescriptor -): UnwrappedType? { - if (SamTypeConversions.conversionDefinitelyNotNeeded(this, candidateParameter)) return null - - val argumentIsFunctional = when (argument) { - is SimpleKotlinCallArgument -> argument.receiver.stableType.isFunctionType - is LambdaKotlinCallArgument, is CallableReferenceKotlinCallArgument -> true - else -> false + override fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean { + return when (argument) { + is SimpleKotlinCallArgument -> argument.receiver.stableType.isFunctionType + is LambdaKotlinCallArgument, is CallableReferenceKotlinCallArgument -> true + else -> false + } } - if (!argumentIsFunctional) return null - val originalExpectedType = argument.getExpectedType(candidateParameter.original, callComponents.languageVersionSettings) + override fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean { + return argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionTypeOrSubtype + } - val convertedTypeByOriginal = - callComponents.samConversionResolver.getFunctionTypeForPossibleSamType( - originalExpectedType, - callComponents.samConversionOracle - ) ?: return null + override fun convertParameterType( + candidate: KotlinResolutionCandidate, + argument: KotlinCallArgument, + parameter: ParameterDescriptor, + expectedParameterType: UnwrappedType + ): UnwrappedType? { + val callComponents = candidate.callComponents + val originalExpectedType = argument.getExpectedType(parameter.original, callComponents.languageVersionSettings) - val candidateExpectedType = argument.getExpectedType(candidateParameter, callComponents.languageVersionSettings) - val convertedTypeByCandidate = - callComponents.samConversionResolver.getFunctionTypeForPossibleSamType( - candidateExpectedType, - callComponents.samConversionOracle + val convertedTypeByOriginal = + callComponents.samConversionResolver.getFunctionTypeForPossibleSamType( + originalExpectedType, + callComponents.samConversionOracle + ) ?: return null + + val convertedTypeByCandidate = + callComponents.samConversionResolver.getFunctionTypeForPossibleSamType( + expectedParameterType, + callComponents.samConversionOracle + ) + + assert(expectedParameterType.constructor == originalExpectedType.constructor && convertedTypeByCandidate != null) { + "If original type is SAM type, then candidate should have same type constructor and corresponding function type\n" + + "originalExpectType: $originalExpectedType, candidateExpectType: $expectedParameterType\n" + + "functionTypeByOriginal: $convertedTypeByOriginal, functionTypeByCandidate: $convertedTypeByCandidate" + } + + candidate.resolvedCall.registerArgumentWithSamConversion( + argument, + SamConversionDescription(convertedTypeByOriginal, convertedTypeByCandidate!!) ) - assert(candidateExpectedType.constructor == originalExpectedType.constructor && convertedTypeByCandidate != null) { - "If original type is SAM type, then candidate should have same type constructor and corresponding function type\n" + - "originalExpectType: $originalExpectedType, candidateExpectType: $candidateExpectedType\n" + - "functionTypeByOriginal: $convertedTypeByOriginal, functionTypeByCandidate: $convertedTypeByCandidate" + val samDescriptor = originalExpectedType.constructor.declarationDescriptor + if (samDescriptor is ClassDescriptor) { + callComponents.lookupTracker.record(candidate.scopeTower.location, samDescriptor, SAM_LOOKUP_NAME) + } + + return convertedTypeByCandidate } - - resolvedCall.registerArgumentWithSamConversion(argument, SamConversionDescription(convertedTypeByOriginal, convertedTypeByCandidate!!)) - - val samDescriptor = originalExpectedType.constructor.declarationDescriptor - if (samDescriptor is ClassDescriptor) { - callComponents.lookupTracker.record(scopeTower.location, samDescriptor, SAM_LOOKUP_NAME) - } - - return convertedTypeByCandidate } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/suspendConversionUtils.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/suspendConversionUtils.kt index a53a9670f6a..4adae8b3ec8 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/suspendConversionUtils.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/suspendConversionUtils.kt @@ -11,11 +11,11 @@ import org.jetbrains.kotlin.descriptors.ParameterDescriptor import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.types.UnwrappedType -object SuspendTypeConversions { - fun conversionDefinitelyNotNeeded( +object SuspendTypeConversions : ParameterTypeConversion { + override fun conversionDefinitelyNotNeeded( candidate: KotlinResolutionCandidate, argument: KotlinCallArgument, - candidateParameter: ParameterDescriptor + expectedParameterType: UnwrappedType ): Boolean { if (!candidate.callComponents.languageVersionSettings.supportsFeature(LanguageFeature.SuspendConversion)) return true @@ -25,34 +25,33 @@ object SuspendTypeConversions { if (!argumentType.isFunctionType) return true if (argumentType.isSuspendFunctionType) return true - if (!candidateParameter.type.isSuspendFunctionType) return true + if (!expectedParameterType.isSuspendFunctionType) return true return false } - fun KotlinResolutionCandidate.conversionMightBeNeededBeforeSubtypingCheck(): Boolean = true - fun KotlinResolutionCandidate.conversionMightBeNeededAfterSubtypingCheck(): Boolean = false + override fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean = true + override fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean = + argument is SimpleKotlinCallArgument && argument.receiver.stableType.isFunctionTypeOrSubtype + + override fun convertParameterType( + candidate: KotlinResolutionCandidate, + argument: KotlinCallArgument, + parameter: ParameterDescriptor, + expectedParameterType: UnwrappedType + ): UnwrappedType? { + val nonSuspendParameterType = createFunctionType( + candidate.callComponents.builtIns, + expectedParameterType.annotations, + expectedParameterType.getReceiverTypeFromFunctionType(), + expectedParameterType.getValueParameterTypesFromFunctionType().map { it.type }, + parameterNames = null, + expectedParameterType.getReturnTypeFromFunctionType(), + suspendFunction = false + ) + + candidate.resolvedCall.registerArgumentWithSuspendConversion(argument, nonSuspendParameterType) + + return nonSuspendParameterType + } } - - -fun KotlinResolutionCandidate.getExpectedTypeWithSuspendConversion( - argument: KotlinCallArgument, - candidateParameter: ParameterDescriptor -): UnwrappedType? { - if (SuspendTypeConversions.conversionDefinitelyNotNeeded(this, argument, candidateParameter)) return null - - val parameterType = candidateParameter.type - val nonSuspendParameterType = createFunctionType( - callComponents.builtIns, - parameterType.annotations, - parameterType.getReceiverTypeFromFunctionType(), - parameterType.getValueParameterTypesFromFunctionType().map { it.type }, - parameterNames = null, - parameterType.getReturnTypeFromFunctionType(), - suspendFunction = false - ) - - resolvedCall.registerArgumentWithSuspendConversion(argument, nonSuspendParameterType) - - return nonSuspendParameterType -} \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/typeConversions.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/typeConversions.kt new file mode 100644 index 00000000000..3943aba87d2 --- /dev/null +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/typeConversions.kt @@ -0,0 +1,107 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.resolve.calls.components + +import org.jetbrains.kotlin.descriptors.ParameterDescriptor +import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument +import org.jetbrains.kotlin.resolve.calls.model.KotlinResolutionCandidate +import org.jetbrains.kotlin.types.UnwrappedType + +interface ParameterTypeConversion { + fun conversionDefinitelyNotNeeded( + candidate: KotlinResolutionCandidate, + argument: KotlinCallArgument, + expectedParameterType: UnwrappedType + ): Boolean + + fun conversionIsNeededBeforeSubtypingCheck(argument: KotlinCallArgument): Boolean + fun conversionIsNeededAfterSubtypingCheck(argument: KotlinCallArgument): Boolean + + fun convertParameterType( + candidate: KotlinResolutionCandidate, + argument: KotlinCallArgument, + parameter: ParameterDescriptor, + expectedParameterType: UnwrappedType + ): UnwrappedType? +} + +object TypeConversions { + fun performCompositeConversionBeforeSubtyping( + candidate: KotlinResolutionCandidate, + argument: KotlinCallArgument, + candidateParameter: ParameterDescriptor, + candidateExpectedType: UnwrappedType, + ): ConversionData { + val samConversionData = performConversionBeforeSubtyping( + candidate, argument, candidateParameter, candidateExpectedType, SamTypeConversions + ) + val suspendConversionData = if (samConversionData.convertedType == null) { + performConversionBeforeSubtyping(candidate, argument, candidateParameter, candidateExpectedType, SuspendTypeConversions) + } else { + null + } + + return ConversionData( + convertedType = samConversionData.convertedType ?: suspendConversionData?.convertedType, + wasConversion = samConversionData.wasConversion || suspendConversionData?.wasConversion == true, + conversionDefinitelyNotNeeded = samConversionData.conversionDefinitelyNotNeeded && + (suspendConversionData == null || suspendConversionData.conversionDefinitelyNotNeeded) + ) + } + + fun performCompositeConversionAfterSubtyping( + candidate: KotlinResolutionCandidate, + argument: KotlinCallArgument, + candidateParameter: ParameterDescriptor, + candidateExpectedType: UnwrappedType, + ): UnwrappedType? { + val samConvertedType = performConversionAfterSubtyping( + candidate, argument, candidateParameter, candidateExpectedType, SamTypeConversions + ) + + if (samConvertedType != null) return samConvertedType + + return performConversionAfterSubtyping(candidate, argument, candidateParameter, candidateExpectedType, SuspendTypeConversions) + } + + private fun performConversionAfterSubtyping( + candidate: KotlinResolutionCandidate, + argument: KotlinCallArgument, + candidateParameter: ParameterDescriptor, + candidateExpectedType: UnwrappedType, + conversion: ParameterTypeConversion + ): UnwrappedType? { + return if ( + conversion.conversionIsNeededAfterSubtypingCheck(argument) && + !conversion.conversionDefinitelyNotNeeded(candidate, argument, candidateExpectedType) + ) { + conversion.convertParameterType(candidate, argument, candidateParameter, candidateExpectedType) + } else { + null + } + } + + private fun performConversionBeforeSubtyping( + candidate: KotlinResolutionCandidate, + argument: KotlinCallArgument, + candidateParameter: ParameterDescriptor, + candidateExpectedType: UnwrappedType, + conversion: ParameterTypeConversion + ): ConversionData { + val conversionDefinitelyNotNeeded = conversion.conversionDefinitelyNotNeeded(candidate, argument, candidateExpectedType) + return if (!conversionDefinitelyNotNeeded && conversion.conversionIsNeededBeforeSubtypingCheck(argument)) { + ConversionData( + conversion.convertParameterType(candidate, argument, candidateParameter, candidateExpectedType), + wasConversion = true, + conversionDefinitelyNotNeeded + ) + } else { + ConversionData(convertedType = null, wasConversion = false, conversionDefinitelyNotNeeded) + } + } + + class ConversionData(val convertedType: UnwrappedType?, val wasConversion: Boolean, val conversionDefinitelyNotNeeded: Boolean) +} diff --git a/compiler/testData/codegen/box/annotations/annotatedLambda/samFunReference.kt b/compiler/testData/codegen/box/annotations/annotatedLambda/samFunReference.kt index fe27a8eaaf4..b90a227d933 100644 --- a/compiler/testData/codegen/box/annotations/annotatedLambda/samFunReference.kt +++ b/compiler/testData/codegen/box/annotations/annotatedLambda/samFunReference.kt @@ -1,5 +1,3 @@ -// !LANGUAGE: -NewInference - // IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM diff --git a/compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt b/compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt new file mode 100644 index 00000000000..0a745303361 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt @@ -0,0 +1,39 @@ +// !LANGUAGE: +SuspendConversion +// WITH_RUNTIME +// WITH_COROUTINES +// IGNORE_BACKEND: JVM, NATIVE, JS, JS_IR +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_LIGHT_ANALYSIS + +import helpers.* +import kotlin.coroutines.* +import kotlin.coroutines.intrinsics.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +suspend fun useSuspendFun(fn : suspend () -> String) = fn() +suspend fun useSuspendFunInt(fn: suspend (Int) -> String) = fn(42) + +suspend fun testIntersection(x: T): String where T : () -> String, T : (Int) -> String { + val a = useSuspendFun(x) + val b = useSuspendFunInt(x) + return a + b +} + +class Test : () -> String, (Int) -> String { + override fun invoke(): String = "OKEmpty" + override fun invoke(p: Int) = "OK$p" +} + +fun box(): String { + var test = "Failed" + builder { + test = testIntersection(Test()) + } + + if (test != "OKEmptyOK42") return "failed: $test" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt b/compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt new file mode 100644 index 00000000000..3b819f6c637 --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt @@ -0,0 +1,39 @@ +// !LANGUAGE: +SuspendConversion +// WITH_RUNTIME +// WITH_COROUTINES +// IGNORE_BACKEND: JVM, NATIVE, JS, JS_IR +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_LIGHT_ANALYSIS + +import helpers.* +import kotlin.coroutines.* +import kotlin.coroutines.intrinsics.* + +fun builder(c: suspend () -> Unit) { + c.startCoroutine(EmptyContinuation) +} + +suspend fun useSuspendFun(fn : suspend () -> String) = fn() +suspend fun useSuspendFunInt(fn: suspend (Int) -> String) = fn(42) + +class Test : () -> String, (Int) -> String { + override fun invoke(): String = "OKEmpty" + override fun invoke(p: Int) = "OK$p" +} + +fun box(): String { + var test = "Failed" + builder { + test = useSuspendFun(Test()) + } + + if (test != "OKEmpty") return "failed 1" + + builder { + test = useSuspendFunInt(Test()) + } + + if (test != "OK42") return "failed 2" + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt b/compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt new file mode 100644 index 00000000000..5b1e9204a47 --- /dev/null +++ b/compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt @@ -0,0 +1,39 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_BACKEND: JS, JS_IR + +fun interface KRunnable { + fun invoke() +} + +fun interface KBoolean { + fun invoke(b: Boolean) +} + +fun useFunInterface(fn: KRunnable) { + fn.invoke() +} +fun useFunInterfacePredicate(fn: KBoolean) { + fn.invoke(true) +} + +fun testIntersection(x: T) where T : () -> Unit, T : (Boolean) -> Unit { + useFunInterface(x) + useFunInterfacePredicate(x) +} + +var result = "" + +object Test : () -> Unit, (Boolean) -> Unit { + override fun invoke() { + result += "O" + } + + override fun invoke(p1: Boolean) { + if (p1) result += "K" + } +} + +fun box(): String { + testIntersection(Test) + return result +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt b/compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt new file mode 100644 index 00000000000..42ab5949744 --- /dev/null +++ b/compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt @@ -0,0 +1,23 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_BACKEND: JS, JS_IR + +fun interface KRunnable { + fun invoke() +} + +object OK : () -> Unit { + override fun invoke() { + result = "OK" + } +} + +fun foo(k: KRunnable) { + k.invoke() +} + +var result: String = "" + +fun box(): String { + foo(OK) + return result +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/javaInterop/samUnboundTypeParameter.kt b/compiler/testData/codegen/box/javaInterop/samUnboundTypeParameter.kt index dbd0d0dfd4a..f8b94dfc059 100644 --- a/compiler/testData/codegen/box/javaInterop/samUnboundTypeParameter.kt +++ b/compiler/testData/codegen/box/javaInterop/samUnboundTypeParameter.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// !LANGUAGE: -NewInference // WITH_RUNTIME // FILE: Base.java import java.lang.Runnable; diff --git a/compiler/testData/codegen/box/sam/passSubtypeOfFunctionSamConversion.kt b/compiler/testData/codegen/box/sam/passSubtypeOfFunctionSamConversion.kt new file mode 100644 index 00000000000..d2b87472604 --- /dev/null +++ b/compiler/testData/codegen/box/sam/passSubtypeOfFunctionSamConversion.kt @@ -0,0 +1,40 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR + +// FILE: a.kt + +object IntMapper : (Int) -> String { + override fun invoke(value: Int): String { + return value.toString() + } +} + +// FILE: Sam.java + +public interface Sam { + R apply(T t); +} + +// FILE: Foo.java + +public class Foo { + public static String bar1(IntMapper mapper) { + return mapper.invoke(0); + } + + public static R bar2(Sam mapper, T input) { + return mapper.apply(input); + } +} + +// FILE: test.kt + +fun box(): String { + val a = Foo.bar1(IntMapper) + if (a != "0") return "Failed 0: $a" + + val b = Foo.bar2(IntMapper, 1) + if (b != "1") return "Failed 1: $b" + + return "OK" +} diff --git a/compiler/testData/diagnostics/tests/samConversions/samConversionsWithSmartCasts.kt b/compiler/testData/diagnostics/tests/samConversions/samConversionsWithSmartCasts.kt index ef861700bf6..387525c939b 100644 --- a/compiler/testData/diagnostics/tests/samConversions/samConversionsWithSmartCasts.kt +++ b/compiler/testData/diagnostics/tests/samConversions/samConversionsWithSmartCasts.kt @@ -49,7 +49,7 @@ fun test6(a: Any) { fun test7(a: (Int) -> Int) { a as () -> Unit - J().run1(a) + J().run1(a) } fun test8(a: () -> Unit) { diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.fir.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.fir.kt new file mode 100644 index 00000000000..8d4d76c4618 --- /dev/null +++ b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.fir.kt @@ -0,0 +1,20 @@ +// !LANGUAGE: +SuspendConversion +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun useSuspendVararg(vararg sfn: suspend () -> Unit) {} + +fun testSuspendConversionInVarargElementsSome( + sf1: suspend () -> Unit, + f2: () -> Unit, + sf3: suspend () -> Unit +) { + useSuspendVararg(sf1, f2, sf3) +} + +fun testSuspendConversionInVarargElementsAll( + f1: () -> Unit, + f2: () -> Unit, + f3: () -> Unit +) { + useSuspendVararg(f1, f2, f3) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.kt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.kt new file mode 100644 index 00000000000..edaf3ee644d --- /dev/null +++ b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.kt @@ -0,0 +1,20 @@ +// !LANGUAGE: +SuspendConversion +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun useSuspendVararg(vararg sfn: suspend () -> Unit) {} + +fun testSuspendConversionInVarargElementsSome( + sf1: suspend () -> Unit, + f2: () -> Unit, + sf3: suspend () -> Unit +) { + useSuspendVararg(sf1, f2, sf3) +} + +fun testSuspendConversionInVarargElementsAll( + f1: () -> Unit, + f2: () -> Unit, + f3: () -> Unit +) { + useSuspendVararg(f1, f2, f3) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.txt b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.txt new file mode 100644 index 00000000000..7762406fa30 --- /dev/null +++ b/compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.txt @@ -0,0 +1,5 @@ +package + +public fun testSuspendConversionInVarargElementsAll(/*0*/ f1: () -> kotlin.Unit, /*1*/ f2: () -> kotlin.Unit, /*2*/ f3: () -> kotlin.Unit): kotlin.Unit +public fun testSuspendConversionInVarargElementsSome(/*0*/ sf1: suspend () -> kotlin.Unit, /*1*/ f2: () -> kotlin.Unit, /*2*/ sf3: suspend () -> kotlin.Unit): kotlin.Unit +public fun useSuspendVararg(/*0*/ vararg sfn: suspend () -> kotlin.Unit /*kotlin.Array kotlin.Unit>*/): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 2dc09770362..765ad65246b 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -23249,6 +23249,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.kt"); } + @TestMetadata("suspendConversionOnVarargElements.kt") + public void testSuspendConversionOnVarargElements() throws Exception { + runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.kt"); + } + @TestMetadata("suspendConversionWithFunInterfaces.kt") public void testSuspendConversionWithFunInterfaces() throws Exception { runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index de9f0a087ef..8ff9a177009 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -23169,6 +23169,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionDisabled.kt"); } + @TestMetadata("suspendConversionOnVarargElements.kt") + public void testSuspendConversionOnVarargElements() throws Exception { + runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionOnVarargElements.kt"); + } + @TestMetadata("suspendConversionWithFunInterfaces.kt") public void testSuspendConversionWithFunInterfaces() throws Exception { runTest("compiler/testData/diagnostics/tests/suspendConversion/suspendConversionWithFunInterfaces.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 308f930e314..6a59ed5dfb1 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -8904,10 +8904,20 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendConversion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @TestMetadata("intersectionTypeToSubtypeConversion.kt") + public void testIntersectionTypeToSubtypeConversion() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt"); + } + @TestMetadata("onArgument.kt") public void testOnArgument() throws Exception { runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt"); } + + @TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt") + public void testSubtypeOfFunctionalTypeToSuspendConversion() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt"); + } } @TestMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine") @@ -12385,6 +12395,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/funInterface/inlinedSamWrapper.kt"); } + @TestMetadata("intersectionTypeToFunInterfaceConversion.kt") + public void testIntersectionTypeToFunInterfaceConversion() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt"); + } + @TestMetadata("multimodule.kt") public void testMultimodule() throws Exception { runTest("compiler/testData/codegen/box/funInterface/multimodule.kt"); @@ -12415,6 +12430,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/funInterface/samConstructorExplicitInvocation.kt"); } + @TestMetadata("subtypeOfFunctionalTypeToFunInterfaceConversion.kt") + public void testSubtypeOfFunctionalTypeToFunInterfaceConversion() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt"); + } + @TestMetadata("suspendFunInterfaceConversionCodegen.kt") public void testSuspendFunInterfaceConversionCodegen() throws Exception { runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt"); @@ -29659,6 +29679,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/sam/partialSamKT.kt"); } + @TestMetadata("passSubtypeOfFunctionSamConversion.kt") + public void testPassSubtypeOfFunctionSamConversion() throws Exception { + runTest("compiler/testData/codegen/box/sam/passSubtypeOfFunctionSamConversion.kt"); + } + @TestMetadata("predicateSamWrapper.kt") public void testPredicateSamWrapper() throws Exception { runTest("compiler/testData/codegen/box/sam/predicateSamWrapper.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index cb5ac5bd663..257d8894889 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -8896,11 +8896,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class SuspendConversion extends AbstractLightAnalysisModeTest { + @TestMetadata("intersectionTypeToSubtypeConversion.kt") + public void ignoreIntersectionTypeToSubtypeConversion() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt"); + } + @TestMetadata("onArgument.kt") public void ignoreOnArgument() throws Exception { runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt"); } + @TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt") + public void ignoreSubtypeOfFunctionalTypeToSuspendConversion() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt"); + } + private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); } @@ -12385,6 +12395,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/funInterface/inlinedSamWrapper.kt"); } + @TestMetadata("intersectionTypeToFunInterfaceConversion.kt") + public void testIntersectionTypeToFunInterfaceConversion() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt"); + } + @TestMetadata("multimodule.kt") public void testMultimodule() throws Exception { runTest("compiler/testData/codegen/box/funInterface/multimodule.kt"); @@ -12415,6 +12430,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/funInterface/samConstructorExplicitInvocation.kt"); } + @TestMetadata("subtypeOfFunctionalTypeToFunInterfaceConversion.kt") + public void testSubtypeOfFunctionalTypeToFunInterfaceConversion() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt"); + } + @TestMetadata("suspendFunInterfaceConversionCodegen.kt") public void testSuspendFunInterfaceConversionCodegen() throws Exception { runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt"); @@ -27293,6 +27313,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/sam/partialSamKT.kt"); } + @TestMetadata("passSubtypeOfFunctionSamConversion.kt") + public void testPassSubtypeOfFunctionSamConversion() throws Exception { + runTest("compiler/testData/codegen/box/sam/passSubtypeOfFunctionSamConversion.kt"); + } + @TestMetadata("predicateSamWrapper.kt") public void testPredicateSamWrapper() throws Exception { runTest("compiler/testData/codegen/box/sam/predicateSamWrapper.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 54c9d556a43..55486423fe0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -7869,10 +7869,20 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendConversion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @TestMetadata("intersectionTypeToSubtypeConversion.kt") + public void testIntersectionTypeToSubtypeConversion() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt"); + } + @TestMetadata("onArgument.kt") public void testOnArgument() throws Exception { runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt"); } + + @TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt") + public void testSubtypeOfFunctionalTypeToSuspendConversion() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt"); + } } @TestMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine") @@ -11170,6 +11180,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/funInterface/inlinedSamWrapper.kt"); } + @TestMetadata("intersectionTypeToFunInterfaceConversion.kt") + public void testIntersectionTypeToFunInterfaceConversion() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt"); + } + @TestMetadata("multimodule.kt") public void testMultimodule() throws Exception { runTest("compiler/testData/codegen/box/funInterface/multimodule.kt"); @@ -11200,6 +11215,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/funInterface/samConstructorExplicitInvocation.kt"); } + @TestMetadata("subtypeOfFunctionalTypeToFunInterfaceConversion.kt") + public void testSubtypeOfFunctionalTypeToFunInterfaceConversion() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt"); + } + @TestMetadata("suspendFunInterfaceConversionCodegen.kt") public void testSuspendFunInterfaceConversionCodegen() throws Exception { runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt"); @@ -28073,6 +28093,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/sam/partialSamKT.kt"); } + @TestMetadata("passSubtypeOfFunctionSamConversion.kt") + public void testPassSubtypeOfFunctionSamConversion() throws Exception { + runTest("compiler/testData/codegen/box/sam/passSubtypeOfFunctionSamConversion.kt"); + } + @TestMetadata("predicateSamWrapper.kt") public void testPredicateSamWrapper() throws Exception { runTest("compiler/testData/codegen/box/sam/predicateSamWrapper.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index cc9580f5437..956947283d6 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -6714,10 +6714,20 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendConversion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } + @TestMetadata("intersectionTypeToSubtypeConversion.kt") + public void testIntersectionTypeToSubtypeConversion() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt"); + } + @TestMetadata("onArgument.kt") public void testOnArgument() throws Exception { runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt"); } + + @TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt") + public void testSubtypeOfFunctionalTypeToSuspendConversion() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt"); + } } @TestMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine") @@ -9580,6 +9590,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/funInterface/inlinedSamWrapper.kt"); } + @TestMetadata("intersectionTypeToFunInterfaceConversion.kt") + public void testIntersectionTypeToFunInterfaceConversion() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt"); + } + @TestMetadata("multimodule.kt") public void testMultimodule() throws Exception { runTest("compiler/testData/codegen/box/funInterface/multimodule.kt"); @@ -9610,6 +9625,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/funInterface/samConstructorExplicitInvocation.kt"); } + @TestMetadata("subtypeOfFunctionalTypeToFunInterfaceConversion.kt") + public void testSubtypeOfFunctionalTypeToFunInterfaceConversion() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt"); + } + @TestMetadata("suspendFunInterfaceConversionCodegen.kt") public void testSuspendFunInterfaceConversionCodegen() throws Exception { runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index b025719a7fe..b5339f3e639 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -6714,10 +6714,20 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/suspendConversion"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } + @TestMetadata("intersectionTypeToSubtypeConversion.kt") + public void testIntersectionTypeToSubtypeConversion() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt"); + } + @TestMetadata("onArgument.kt") public void testOnArgument() throws Exception { runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt"); } + + @TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt") + public void testSubtypeOfFunctionalTypeToSuspendConversion() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt"); + } } @TestMetadata("compiler/testData/codegen/box/coroutines/suspendFunctionAsCoroutine") @@ -9580,6 +9590,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/funInterface/inlinedSamWrapper.kt"); } + @TestMetadata("intersectionTypeToFunInterfaceConversion.kt") + public void testIntersectionTypeToFunInterfaceConversion() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt"); + } + @TestMetadata("multimodule.kt") public void testMultimodule() throws Exception { runTest("compiler/testData/codegen/box/funInterface/multimodule.kt"); @@ -9610,6 +9625,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/funInterface/samConstructorExplicitInvocation.kt"); } + @TestMetadata("subtypeOfFunctionalTypeToFunInterfaceConversion.kt") + public void testSubtypeOfFunctionalTypeToFunInterfaceConversion() throws Exception { + runTest("compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt"); + } + @TestMetadata("suspendFunInterfaceConversionCodegen.kt") public void testSuspendFunInterfaceConversionCodegen() throws Exception { runTest("compiler/testData/codegen/box/funInterface/suspendFunInterfaceConversionCodegen.kt");