From 0d9ad62d4a63129bac70e664c293a6f9ec70b1cc Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Tue, 23 Nov 2021 10:25:07 +0300 Subject: [PATCH] Fix inference for lambdas with with extension function expected type ^KT-49832 Fixed ^KT-49836 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 24 +++++ ...irOldFrontendDiagnosticsTestGenerated.java | 24 +++++ ...DiagnosticsWithLightTreeTestGenerated.java | 24 +++++ .../ConeConstraintSystemUtilContext.kt | 8 ++ .../resolve/inference/InferenceComponents.kt | 4 +- .../components/ConstraintSystemUtilContext.kt | 3 + .../PostponedArgumentInputTypesResolver.kt | 95 ++++++++++++++++--- .../ClassicConstraintSystemUtilContext.kt | 6 ++ .../selectOfLambdaWithExtension.fir.kt | 20 ++++ .../inference/selectOfLambdaWithExtension.kt | 20 ++++ ...selectOfLambdaWithExtensionDisabled.fir.kt | 21 ++++ .../selectOfLambdaWithExtensionDisabled.kt | 21 ++++ .../selectOfLambdaWithExtensionEnabled.kt | 22 +++++ .../inference/specialCallsWithLambdas.kt | 19 ++++ .../test/runners/DiagnosticTestGenerated.java | 24 +++++ .../kotlin/config/LanguageVersionSettings.kt | 1 + 16 files changed, 320 insertions(+), 16 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtension.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtension.kt create mode 100644 compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionDisabled.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionDisabled.kt create mode 100644 compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionEnabled.kt create mode 100644 compiler/testData/diagnostics/tests/inference/specialCallsWithLambdas.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 9685a57dbe1..02854175df2 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -13453,12 +13453,36 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/inference/returningLambdaInSuspendContext.kt"); } + @Test + @TestMetadata("selectOfLambdaWithExtension.kt") + public void testSelectOfLambdaWithExtension() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtension.kt"); + } + + @Test + @TestMetadata("selectOfLambdaWithExtensionDisabled.kt") + public void testSelectOfLambdaWithExtensionDisabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionDisabled.kt"); + } + + @Test + @TestMetadata("selectOfLambdaWithExtensionEnabled.kt") + public void testSelectOfLambdaWithExtensionEnabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionEnabled.kt"); + } + @Test @TestMetadata("specialCallsWithCallableReferences.kt") public void testSpecialCallsWithCallableReferences() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/specialCallsWithCallableReferences.kt"); } + @Test + @TestMetadata("specialCallsWithLambdas.kt") + public void testSpecialCallsWithLambdas() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/specialCallsWithLambdas.kt"); + } + @Test @TestMetadata("starApproximation.kt") public void testStarApproximation() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index f755bd416ba..6280d3022c3 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -13453,12 +13453,36 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/inference/returningLambdaInSuspendContext.kt"); } + @Test + @TestMetadata("selectOfLambdaWithExtension.kt") + public void testSelectOfLambdaWithExtension() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtension.kt"); + } + + @Test + @TestMetadata("selectOfLambdaWithExtensionDisabled.kt") + public void testSelectOfLambdaWithExtensionDisabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionDisabled.kt"); + } + + @Test + @TestMetadata("selectOfLambdaWithExtensionEnabled.kt") + public void testSelectOfLambdaWithExtensionEnabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionEnabled.kt"); + } + @Test @TestMetadata("specialCallsWithCallableReferences.kt") public void testSpecialCallsWithCallableReferences() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/specialCallsWithCallableReferences.kt"); } + @Test + @TestMetadata("specialCallsWithLambdas.kt") + public void testSpecialCallsWithLambdas() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/specialCallsWithLambdas.kt"); + } + @Test @TestMetadata("starApproximation.kt") public void testStarApproximation() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index e9c2b243242..0f533bd9884 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -13453,12 +13453,36 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/inference/returningLambdaInSuspendContext.kt"); } + @Test + @TestMetadata("selectOfLambdaWithExtension.kt") + public void testSelectOfLambdaWithExtension() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtension.kt"); + } + + @Test + @TestMetadata("selectOfLambdaWithExtensionDisabled.kt") + public void testSelectOfLambdaWithExtensionDisabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionDisabled.kt"); + } + + @Test + @TestMetadata("selectOfLambdaWithExtensionEnabled.kt") + public void testSelectOfLambdaWithExtensionEnabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionEnabled.kt"); + } + @Test @TestMetadata("specialCallsWithCallableReferences.kt") public void testSpecialCallsWithCallableReferences() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/specialCallsWithCallableReferences.kt"); } + @Test + @TestMetadata("specialCallsWithLambdas.kt") + public void testSpecialCallsWithLambdas() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/specialCallsWithLambdas.kt"); + } + @Test @TestMetadata("starApproximation.kt") public void testStarApproximation() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt index b9a10e0ad28..8ff45bde86a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt @@ -91,6 +91,11 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext { return this is LambdaWithTypeVariableAsExpectedTypeAtom && !this.atom.anonymousFunction.isLambda && this.atom.anonymousFunction.receiverTypeRef?.coneType != null } + override fun PostponedAtomWithRevisableExpectedType.isLambda(): Boolean { + require(this is PostponedResolvedAtom) + return this is LambdaWithTypeVariableAsExpectedTypeAtom && this.atom.anonymousFunction.isLambda + } + override fun createTypeVariableForLambdaReturnType(): TypeVariableMarker { return ConeTypeVariableForPostponedAtom(PostponedArgumentInputTypesResolver.TYPE_VARIABLE_NAME_FOR_LAMBDA_RETURN_TYPE) } @@ -117,4 +122,7 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext { override fun createTypeVariableForCallableReferenceReturnType(): TypeVariableMarker { return ConeTypeVariableForPostponedAtom(PostponedArgumentInputTypesResolver.TYPE_VARIABLE_NAME_FOR_LAMBDA_RETURN_TYPE) } + + override val isForcedConsiderExtensionReceiverFromConstrainsInLambda: Boolean + get() = true } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceComponents.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceComponents.kt index c1d66060d52..c9271262ee9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceComponents.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/InferenceComponents.kt @@ -30,7 +30,9 @@ class InferenceComponents(val session: FirSession) : FirSessionComponent { val resultTypeResolver = ResultTypeResolver(approximator, trivialConstraintTypeInferenceOracle, session.languageVersionSettings) val variableFixationFinder = VariableFixationFinder(trivialConstraintTypeInferenceOracle, session.languageVersionSettings) val postponedArgumentInputTypesResolver = - PostponedArgumentInputTypesResolver(resultTypeResolver, variableFixationFinder, ConeConstraintSystemUtilContext) + PostponedArgumentInputTypesResolver( + resultTypeResolver, variableFixationFinder, ConeConstraintSystemUtilContext, session.languageVersionSettings + ) val constraintSystemFactory = ConstraintSystemFactory() diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemUtilContext.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemUtilContext.kt index f9cf5f73ea2..e2c1b71701c 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemUtilContext.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintSystemUtilContext.kt @@ -29,6 +29,7 @@ interface ConstraintSystemUtilContext { fun extractLambdaParameterTypesFromDeclaration(declaration: PostponedAtomWithRevisableExpectedType): List? fun PostponedAtomWithRevisableExpectedType.isFunctionExpression(): Boolean fun PostponedAtomWithRevisableExpectedType.isFunctionExpressionWithReceiver(): Boolean + fun PostponedAtomWithRevisableExpectedType.isLambda(): Boolean fun createTypeVariableForLambdaReturnType(): TypeVariableMarker fun createTypeVariableForLambdaParameterType(argument: PostponedAtomWithRevisableExpectedType, index: Int): TypeVariableMarker fun createTypeVariableForCallableReferenceReturnType(): TypeVariableMarker @@ -36,4 +37,6 @@ interface ConstraintSystemUtilContext { argument: PostponedAtomWithRevisableExpectedType, index: Int ): TypeVariableMarker + + val isForcedConsiderExtensionReceiverFromConstrainsInLambda get() = false } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/PostponedArgumentInputTypesResolver.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/PostponedArgumentInputTypesResolver.kt index 9e0a55fcda2..039ccd215b6 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/PostponedArgumentInputTypesResolver.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/PostponedArgumentInputTypesResolver.kt @@ -5,6 +5,8 @@ package org.jetbrains.kotlin.resolve.calls.inference.components +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.resolve.calls.inference.model.* import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.types.model.* @@ -19,6 +21,7 @@ class PostponedArgumentInputTypesResolver( private val resultTypeResolver: ResultTypeResolver, private val variableFixationFinder: VariableFixationFinder, private val resolutionTypeSystemContext: ConstraintSystemUtilContext, + private val languageVersionSettings: LanguageVersionSettings, ) { private class ParameterTypesInfo( val parametersFromDeclaration: List?, @@ -79,12 +82,19 @@ class PostponedArgumentInputTypesResolver( val annotations = functionalTypesFromConstraints?.map { it.type.getAnnotations() }?.flatten()?.distinct() - // An extension function flag can only come from a declaration of anonymous function: `select({ this + it }, fun Int.(x: Int) = 10)` - val (parameterTypesFromDeclarationOfRelatedLambdas, isThereExtensionFunctionAmongRelatedLambdas) = - getDeclaredParametersFromRelatedLambdas(argument, postponedArguments, variableDependencyProvider) - val extensionFunctionTypePresentInConstraints = functionalTypesFromConstraints?.any { it.type.isExtensionFunctionType() } == true + // An extension function flag can only come from a declaration of anonymous function: `select({ this + it }, fun Int.(x: Int) = 10)` + val (parameterTypesFromDeclarationOfRelatedLambdas, isThereExtensionFunctionAmongRelatedLambdas, maxParameterCount) = + computeParameterInfoFromRelatedLambdas( + argument, + postponedArguments, + variableDependencyProvider, + extensionFunctionTypePresentInConstraints, + parameterTypesFromConstraints, + parameterTypesFromDeclaration, + ) + var isSuspend = false var isNullable = false if (!functionalTypesFromConstraints.isNullOrEmpty()) { @@ -95,23 +105,47 @@ class PostponedArgumentInputTypesResolver( if (isSuspend && !isNullable) break } } + + val isLambda = with(resolutionTypeSystemContext) { + argument.isLambda() + } + + val isExtensionFunction = isThereExtensionFunctionAmongRelatedLambdas || extensionFunctionTypePresentInConstraints return ParameterTypesInfo( - parameterTypesFromDeclaration, + if (parameterTypesFromDeclaration != null && isLambda && + parameterTypesFromDeclaration.size + 1 == maxParameterCount && + isExtensionFunction && considerExtensionReceiverFromConstrainsInLambda() + ) + listOf(null) + parameterTypesFromDeclaration + else + parameterTypesFromDeclaration, parameterTypesFromDeclarationOfRelatedLambdas, parameterTypesFromConstraints, annotations = annotations, - isExtensionFunction = isThereExtensionFunctionAmongRelatedLambdas || extensionFunctionTypePresentInConstraints, + isExtensionFunction, isSuspend = isSuspend, isNullable = isNullable ) } - private fun Context.getDeclaredParametersFromRelatedLambdas( + // Components: + // 1. Set of List of known parameter types (some of them aligned with null-prefix for absent extension receiver) + // 2. isAnyFunctionExpressionWithReceiver + // 3. maxParameterCount + private fun Context.computeParameterInfoFromRelatedLambdas( argument: PostponedAtomWithRevisableExpectedType, postponedArguments: List, - dependencyProvider: TypeVariableDependencyInformationProvider - ): Pair>?, Boolean> = with(resolutionTypeSystemContext) { - val parameterTypesFromDeclarationOfRelatedLambdas = postponedArguments + dependencyProvider: TypeVariableDependencyInformationProvider, + extensionFunctionTypePresentInConstraints: Boolean, + parameterTypesFromConstraints: Set>?, + parameterTypesFromDeclaration: List?, + ): Triple>?, Boolean, Int> = with(resolutionTypeSystemContext) { + var isAnyFunctionExpressionWithReceiver = false + + // For each lambda/function expression: + // - First component: list of parameter types (for lambdas, it doesn't include receiver) + // - Second component: is lambda + val parameterTypesFromDeclarationOfRelatedLambdas: List, Boolean>> = postponedArguments .mapNotNull { anotherArgument -> when { anotherArgument !is LambdaWithTypeVariableAsExpectedTypeMarker -> null @@ -123,19 +157,47 @@ class PostponedArgumentInputTypesResolver( val areTypeVariablesRelated = dependencyProvider.areVariablesDependentShallowly( argumentExpectedTypeConstructor, anotherArgumentExpectedTypeConstructor ) - val isAnonymousExtensionFunction = anotherArgument.isFunctionExpressionWithReceiver() + isAnyFunctionExpressionWithReceiver = + isAnyFunctionExpressionWithReceiver or anotherArgument.isFunctionExpressionWithReceiver() + val parameterTypesFromDeclarationOfRelatedLambda = anotherArgument.parameterTypesFromDeclaration if (areTypeVariablesRelated && parameterTypesFromDeclarationOfRelatedLambda != null) { - parameterTypesFromDeclarationOfRelatedLambda to isAnonymousExtensionFunction + Pair(parameterTypesFromDeclarationOfRelatedLambda, anotherArgument.isLambda()) } else null } } } - return parameterTypesFromDeclarationOfRelatedLambdas.run { mapTo(SmartSet.create()) { it.first } to any { it.second } } + val declaredParameterTypes = mutableSetOf>() + + val maxParameterCount = maxOf( + parameterTypesFromConstraints?.map { it.size }?.maxOrNull() ?: 0, + parameterTypesFromDeclarationOfRelatedLambdas.map { it.first.size }.maxOrNull() ?: 0, + parameterTypesFromDeclaration?.size ?: 0 + ) + + val isFeatureEnabled = + considerExtensionReceiverFromConstrainsInLambda() + + parameterTypesFromDeclarationOfRelatedLambdas.mapTo(declaredParameterTypes) { (types, isLambda) -> + if ( + isFeatureEnabled && isLambda && + (extensionFunctionTypePresentInConstraints || isAnyFunctionExpressionWithReceiver) && + types.size + 1 == maxParameterCount + ) + listOf(null) + types + else + types + } + + return Triple(declaredParameterTypes, isAnyFunctionExpressionWithReceiver, maxParameterCount) } + private fun considerExtensionReceiverFromConstrainsInLambda() = + resolutionTypeSystemContext.isForcedConsiderExtensionReceiverFromConstrainsInLambda || + languageVersionSettings.supportsFeature(LanguageFeature.ConsiderExtensionReceiverFromConstrainsInLambda) + private fun Context.createTypeVariableForReturnType(argument: PostponedAtomWithRevisableExpectedType): TypeVariableMarker = with(resolutionTypeSystemContext) { return when (argument) { @@ -443,7 +505,10 @@ class PostponedArgumentInputTypesResolver( private fun getDeclaredParametersConsideringExtensionFunctionsPresence(parameterTypesInfo: ParameterTypesInfo): List? = with(parameterTypesInfo) { - if (parametersFromConstraints.isNullOrEmpty() || parametersFromDeclaration.isNullOrEmpty()) + // If the feature is enabled, null for extension parameter has been added in different place already + if (considerExtensionReceiverFromConstrainsInLambda() || + parametersFromConstraints.isNullOrEmpty() || parametersFromDeclaration.isNullOrEmpty() + ) parametersFromDeclaration else { val oneLessParameterInDeclarationThanInConstraints = @@ -529,4 +594,4 @@ class PostponedArgumentInputTypesResolver( const val TYPE_VARIABLE_NAME_PREFIX_FOR_CR_PARAMETER_TYPE = "_QP" const val TYPE_VARIABLE_NAME_FOR_CR_RETURN_TYPE = "_Q" } -} \ No newline at end of file +} diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ClassicConstraintSystemUtilContext.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ClassicConstraintSystemUtilContext.kt index aacd048dfab..dff6f6446c3 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ClassicConstraintSystemUtilContext.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ClassicConstraintSystemUtilContext.kt @@ -83,6 +83,12 @@ class ClassicConstraintSystemUtilContext( return atom is FunctionExpression && atom.receiverType != null } + override fun PostponedAtomWithRevisableExpectedType.isLambda(): Boolean { + require(this is ResolvedAtom) + val atom = this.atom + return atom is LambdaKotlinCallArgument && atom !is FunctionExpression + } + override fun createTypeVariableForLambdaReturnType(): TypeVariableMarker { return TypeVariableForLambdaReturnType( builtIns, diff --git a/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtension.fir.kt b/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtension.fir.kt new file mode 100644 index 00000000000..3dd73cd47bb --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtension.fir.kt @@ -0,0 +1,20 @@ +// SKIP_TXT + +typealias A = CharSequence.(Int) -> Unit + +var w: Int = 1 + +fun myPrint(x: Int) {} + +fun select(vararg x: T) = x[0] + +val a1: A = select( + { a: Int -> myPrint(a + this.length + 1) }, + { a: Int -> myPrint(a + this.length + 2) } +) + +val a2 = select( + { a: Int -> myPrint(a + this.length + 1) }, + fun CharSequence.(a: Int) { myPrint(a + this.length + 2) }, + { a: Int -> myPrint(a + this.length + 3) } +) diff --git a/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtension.kt b/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtension.kt new file mode 100644 index 00000000000..2a1d0c96c28 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtension.kt @@ -0,0 +1,20 @@ +// SKIP_TXT + +typealias A = CharSequence.(Int) -> Unit + +var w: Int = 1 + +fun myPrint(x: Int) {} + +fun select(vararg x: T) = x[0] + +val a1: A = select( + { a: Int -> myPrint(a + this.length + 1) }, + { a: Int -> myPrint(a + this.length + 2) } +) + +val a2 = select( + { a: Int -> myPrint(a + this.length + 1) }, + fun CharSequence.(a: Int) { myPrint(a + this.length + 2) }, + { a: Int -> myPrint(a + this.length + 3) } +) diff --git a/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionDisabled.fir.kt b/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionDisabled.fir.kt new file mode 100644 index 00000000000..a48d601a84a --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionDisabled.fir.kt @@ -0,0 +1,21 @@ +// !LANGUAGE: -ConsiderExtensionReceiverFromConstrainsInLambda +// SKIP_TXT + +typealias A = CharSequence.(Int) -> Unit + +var w: Int = 1 + +fun myPrint(x: Int) {} + +fun select(vararg x: T) = x[0] + +val a1: A = select( + { a: Int -> myPrint(a + this.length + 1) }, + { a: Int -> myPrint(a + this.length + 2) } +) + +val a2 = select( + { a: Int -> myPrint(a + this.length + 1) }, + fun CharSequence.(a: Int) { myPrint(a + this.length + 2) }, + { a: Int -> myPrint(a + this.length + 3) } +) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionDisabled.kt b/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionDisabled.kt new file mode 100644 index 00000000000..549d54327fa --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionDisabled.kt @@ -0,0 +1,21 @@ +// !LANGUAGE: -ConsiderExtensionReceiverFromConstrainsInLambda +// SKIP_TXT + +typealias A = CharSequence.(Int) -> Unit + +var w: Int = 1 + +fun myPrint(x: Int) {} + +fun select(vararg x: T) = x[0] + +val a1: A = select( + { a: Int -> myPrint(a + this.length + 1) }, + { a: Int -> myPrint(a + this.length + 2) } +) + +val a2 = select( + { a: Int -> myPrint(a + this.length + 1) }, + fun CharSequence.(a: Int) { myPrint(a + this.length + 2) }, + { a: Int -> myPrint(a + this.length + 3) } +) diff --git a/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionEnabled.kt b/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionEnabled.kt new file mode 100644 index 00000000000..84b849f18ff --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionEnabled.kt @@ -0,0 +1,22 @@ +// !LANGUAGE: +ConsiderExtensionReceiverFromConstrainsInLambda +// FIR_IDENTICAL +// SKIP_TXT + +typealias A = CharSequence.(Int) -> Unit + +var w: Int = 1 + +fun myPrint(x: Int) {} + +fun select(vararg x: T) = x[0] + +val a1: A = select( + { a: Int -> myPrint(a + this.length + 1) }, + { a: Int -> myPrint(a + this.length + 2) } +) + +val a2 = select( + { a: Int -> myPrint(a + this.length + 1) }, + fun CharSequence.(a: Int) { myPrint(a + this.length + 2) }, + { a: Int -> myPrint(a + this.length + 3) } +) diff --git a/compiler/testData/diagnostics/tests/inference/specialCallsWithLambdas.kt b/compiler/testData/diagnostics/tests/inference/specialCallsWithLambdas.kt new file mode 100644 index 00000000000..a72c4ac986e --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/specialCallsWithLambdas.kt @@ -0,0 +1,19 @@ +// FIR_IDENTICAL +// SKIP_TXT + +typealias A = CharSequence.(Int) -> Unit + +var w: Int = 1 + +fun myPrint(x: Int) {} + +val a1: A = when (w) { + 1 -> { a: Int -> myPrint(a + this.length + 1) } + else -> { a: Int -> myPrint(a + this.length + 2) } +} + +val a2: A = try { + { a: Int -> myPrint(a + this.length + 1) } +} catch (t: Throwable) { + { a: Int -> myPrint(a + this.length + 2) } +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 42c1b0433e4..3b80d78a345 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -13459,12 +13459,36 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/inference/returningLambdaInSuspendContext.kt"); } + @Test + @TestMetadata("selectOfLambdaWithExtension.kt") + public void testSelectOfLambdaWithExtension() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtension.kt"); + } + + @Test + @TestMetadata("selectOfLambdaWithExtensionDisabled.kt") + public void testSelectOfLambdaWithExtensionDisabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionDisabled.kt"); + } + + @Test + @TestMetadata("selectOfLambdaWithExtensionEnabled.kt") + public void testSelectOfLambdaWithExtensionEnabled() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/selectOfLambdaWithExtensionEnabled.kt"); + } + @Test @TestMetadata("specialCallsWithCallableReferences.kt") public void testSpecialCallsWithCallableReferences() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/specialCallsWithCallableReferences.kt"); } + @Test + @TestMetadata("specialCallsWithLambdas.kt") + public void testSpecialCallsWithLambdas() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/specialCallsWithLambdas.kt"); + } + @Test @TestMetadata("starApproximation.kt") public void testStarApproximation() throws Exception { diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 98dc148ea8a..033cc833719 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -241,6 +241,7 @@ enum class LanguageFeature( PartiallySpecifiedTypeArguments(KOTLIN_1_7), EliminateAmbiguitiesWithExternalTypeParameters(KOTLIN_1_7), EliminateAmbiguitiesOnInheritedSamInterfaces(KOTLIN_1_7), + ConsiderExtensionReceiverFromConstrainsInLambda(KOTLIN_1_7, kind = BUG_FIX), // KT-49832 // 1.8