Fix inference for lambdas with with extension function expected type

^KT-49832 Fixed
^KT-49836 Fixed
This commit is contained in:
Denis.Zharkov
2021-11-23 10:25:07 +03:00
committed by teamcityserver
parent 3fb17cfa9a
commit 0d9ad62d4a
16 changed files with 320 additions and 16 deletions
@@ -13453,12 +13453,36 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/inference/returningLambdaInSuspendContext.kt"); 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 @Test
@TestMetadata("specialCallsWithCallableReferences.kt") @TestMetadata("specialCallsWithCallableReferences.kt")
public void testSpecialCallsWithCallableReferences() throws Exception { public void testSpecialCallsWithCallableReferences() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/specialCallsWithCallableReferences.kt"); 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 @Test
@TestMetadata("starApproximation.kt") @TestMetadata("starApproximation.kt")
public void testStarApproximation() throws Exception { public void testStarApproximation() throws Exception {
@@ -13453,12 +13453,36 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/inference/returningLambdaInSuspendContext.kt"); 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 @Test
@TestMetadata("specialCallsWithCallableReferences.kt") @TestMetadata("specialCallsWithCallableReferences.kt")
public void testSpecialCallsWithCallableReferences() throws Exception { public void testSpecialCallsWithCallableReferences() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/specialCallsWithCallableReferences.kt"); 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 @Test
@TestMetadata("starApproximation.kt") @TestMetadata("starApproximation.kt")
public void testStarApproximation() throws Exception { public void testStarApproximation() throws Exception {
@@ -13453,12 +13453,36 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/inference/returningLambdaInSuspendContext.kt"); 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 @Test
@TestMetadata("specialCallsWithCallableReferences.kt") @TestMetadata("specialCallsWithCallableReferences.kt")
public void testSpecialCallsWithCallableReferences() throws Exception { public void testSpecialCallsWithCallableReferences() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/specialCallsWithCallableReferences.kt"); 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 @Test
@TestMetadata("starApproximation.kt") @TestMetadata("starApproximation.kt")
public void testStarApproximation() throws Exception { public void testStarApproximation() throws Exception {
@@ -91,6 +91,11 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext {
return this is LambdaWithTypeVariableAsExpectedTypeAtom && !this.atom.anonymousFunction.isLambda && this.atom.anonymousFunction.receiverTypeRef?.coneType != null 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 { override fun createTypeVariableForLambdaReturnType(): TypeVariableMarker {
return ConeTypeVariableForPostponedAtom(PostponedArgumentInputTypesResolver.TYPE_VARIABLE_NAME_FOR_LAMBDA_RETURN_TYPE) return ConeTypeVariableForPostponedAtom(PostponedArgumentInputTypesResolver.TYPE_VARIABLE_NAME_FOR_LAMBDA_RETURN_TYPE)
} }
@@ -117,4 +122,7 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext {
override fun createTypeVariableForCallableReferenceReturnType(): TypeVariableMarker { override fun createTypeVariableForCallableReferenceReturnType(): TypeVariableMarker {
return ConeTypeVariableForPostponedAtom(PostponedArgumentInputTypesResolver.TYPE_VARIABLE_NAME_FOR_LAMBDA_RETURN_TYPE) return ConeTypeVariableForPostponedAtom(PostponedArgumentInputTypesResolver.TYPE_VARIABLE_NAME_FOR_LAMBDA_RETURN_TYPE)
} }
override val isForcedConsiderExtensionReceiverFromConstrainsInLambda: Boolean
get() = true
} }
@@ -30,7 +30,9 @@ class InferenceComponents(val session: FirSession) : FirSessionComponent {
val resultTypeResolver = ResultTypeResolver(approximator, trivialConstraintTypeInferenceOracle, session.languageVersionSettings) val resultTypeResolver = ResultTypeResolver(approximator, trivialConstraintTypeInferenceOracle, session.languageVersionSettings)
val variableFixationFinder = VariableFixationFinder(trivialConstraintTypeInferenceOracle, session.languageVersionSettings) val variableFixationFinder = VariableFixationFinder(trivialConstraintTypeInferenceOracle, session.languageVersionSettings)
val postponedArgumentInputTypesResolver = val postponedArgumentInputTypesResolver =
PostponedArgumentInputTypesResolver(resultTypeResolver, variableFixationFinder, ConeConstraintSystemUtilContext) PostponedArgumentInputTypesResolver(
resultTypeResolver, variableFixationFinder, ConeConstraintSystemUtilContext, session.languageVersionSettings
)
val constraintSystemFactory = ConstraintSystemFactory() val constraintSystemFactory = ConstraintSystemFactory()
@@ -29,6 +29,7 @@ interface ConstraintSystemUtilContext {
fun extractLambdaParameterTypesFromDeclaration(declaration: PostponedAtomWithRevisableExpectedType): List<KotlinTypeMarker?>? fun extractLambdaParameterTypesFromDeclaration(declaration: PostponedAtomWithRevisableExpectedType): List<KotlinTypeMarker?>?
fun PostponedAtomWithRevisableExpectedType.isFunctionExpression(): Boolean fun PostponedAtomWithRevisableExpectedType.isFunctionExpression(): Boolean
fun PostponedAtomWithRevisableExpectedType.isFunctionExpressionWithReceiver(): Boolean fun PostponedAtomWithRevisableExpectedType.isFunctionExpressionWithReceiver(): Boolean
fun PostponedAtomWithRevisableExpectedType.isLambda(): Boolean
fun createTypeVariableForLambdaReturnType(): TypeVariableMarker fun createTypeVariableForLambdaReturnType(): TypeVariableMarker
fun createTypeVariableForLambdaParameterType(argument: PostponedAtomWithRevisableExpectedType, index: Int): TypeVariableMarker fun createTypeVariableForLambdaParameterType(argument: PostponedAtomWithRevisableExpectedType, index: Int): TypeVariableMarker
fun createTypeVariableForCallableReferenceReturnType(): TypeVariableMarker fun createTypeVariableForCallableReferenceReturnType(): TypeVariableMarker
@@ -36,4 +37,6 @@ interface ConstraintSystemUtilContext {
argument: PostponedAtomWithRevisableExpectedType, argument: PostponedAtomWithRevisableExpectedType,
index: Int index: Int
): TypeVariableMarker ): TypeVariableMarker
val isForcedConsiderExtensionReceiverFromConstrainsInLambda get() = false
} }
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.resolve.calls.inference.components 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.inference.model.*
import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.types.model.*
@@ -19,6 +21,7 @@ class PostponedArgumentInputTypesResolver(
private val resultTypeResolver: ResultTypeResolver, private val resultTypeResolver: ResultTypeResolver,
private val variableFixationFinder: VariableFixationFinder, private val variableFixationFinder: VariableFixationFinder,
private val resolutionTypeSystemContext: ConstraintSystemUtilContext, private val resolutionTypeSystemContext: ConstraintSystemUtilContext,
private val languageVersionSettings: LanguageVersionSettings,
) { ) {
private class ParameterTypesInfo( private class ParameterTypesInfo(
val parametersFromDeclaration: List<KotlinTypeMarker?>?, val parametersFromDeclaration: List<KotlinTypeMarker?>?,
@@ -79,12 +82,19 @@ class PostponedArgumentInputTypesResolver(
val annotations = functionalTypesFromConstraints?.map { it.type.getAnnotations() }?.flatten()?.distinct() 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 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 isSuspend = false
var isNullable = false var isNullable = false
if (!functionalTypesFromConstraints.isNullOrEmpty()) { if (!functionalTypesFromConstraints.isNullOrEmpty()) {
@@ -95,23 +105,47 @@ class PostponedArgumentInputTypesResolver(
if (isSuspend && !isNullable) break if (isSuspend && !isNullable) break
} }
} }
val isLambda = with(resolutionTypeSystemContext) {
argument.isLambda()
}
val isExtensionFunction = isThereExtensionFunctionAmongRelatedLambdas || extensionFunctionTypePresentInConstraints
return ParameterTypesInfo( return ParameterTypesInfo(
parameterTypesFromDeclaration, if (parameterTypesFromDeclaration != null && isLambda &&
parameterTypesFromDeclaration.size + 1 == maxParameterCount &&
isExtensionFunction && considerExtensionReceiverFromConstrainsInLambda()
)
listOf(null) + parameterTypesFromDeclaration
else
parameterTypesFromDeclaration,
parameterTypesFromDeclarationOfRelatedLambdas, parameterTypesFromDeclarationOfRelatedLambdas,
parameterTypesFromConstraints, parameterTypesFromConstraints,
annotations = annotations, annotations = annotations,
isExtensionFunction = isThereExtensionFunctionAmongRelatedLambdas || extensionFunctionTypePresentInConstraints, isExtensionFunction,
isSuspend = isSuspend, isSuspend = isSuspend,
isNullable = isNullable 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, argument: PostponedAtomWithRevisableExpectedType,
postponedArguments: List<PostponedAtomWithRevisableExpectedType>, postponedArguments: List<PostponedAtomWithRevisableExpectedType>,
dependencyProvider: TypeVariableDependencyInformationProvider dependencyProvider: TypeVariableDependencyInformationProvider,
): Pair<Set<List<KotlinTypeMarker?>>?, Boolean> = with(resolutionTypeSystemContext) { extensionFunctionTypePresentInConstraints: Boolean,
val parameterTypesFromDeclarationOfRelatedLambdas = postponedArguments parameterTypesFromConstraints: Set<List<TypeWithKind>>?,
parameterTypesFromDeclaration: List<KotlinTypeMarker?>?,
): Triple<Set<List<KotlinTypeMarker?>>?, 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<Pair<List<KotlinTypeMarker?>, Boolean>> = postponedArguments
.mapNotNull { anotherArgument -> .mapNotNull { anotherArgument ->
when { when {
anotherArgument !is LambdaWithTypeVariableAsExpectedTypeMarker -> null anotherArgument !is LambdaWithTypeVariableAsExpectedTypeMarker -> null
@@ -123,19 +157,47 @@ class PostponedArgumentInputTypesResolver(
val areTypeVariablesRelated = dependencyProvider.areVariablesDependentShallowly( val areTypeVariablesRelated = dependencyProvider.areVariablesDependentShallowly(
argumentExpectedTypeConstructor, anotherArgumentExpectedTypeConstructor argumentExpectedTypeConstructor, anotherArgumentExpectedTypeConstructor
) )
val isAnonymousExtensionFunction = anotherArgument.isFunctionExpressionWithReceiver() isAnyFunctionExpressionWithReceiver =
isAnyFunctionExpressionWithReceiver or anotherArgument.isFunctionExpressionWithReceiver()
val parameterTypesFromDeclarationOfRelatedLambda = anotherArgument.parameterTypesFromDeclaration val parameterTypesFromDeclarationOfRelatedLambda = anotherArgument.parameterTypesFromDeclaration
if (areTypeVariablesRelated && parameterTypesFromDeclarationOfRelatedLambda != null) { if (areTypeVariablesRelated && parameterTypesFromDeclarationOfRelatedLambda != null) {
parameterTypesFromDeclarationOfRelatedLambda to isAnonymousExtensionFunction Pair(parameterTypesFromDeclarationOfRelatedLambda, anotherArgument.isLambda())
} else null } else null
} }
} }
} }
return parameterTypesFromDeclarationOfRelatedLambdas.run { mapTo(SmartSet.create()) { it.first } to any { it.second } } val declaredParameterTypes = mutableSetOf<List<KotlinTypeMarker?>>()
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 = private fun Context.createTypeVariableForReturnType(argument: PostponedAtomWithRevisableExpectedType): TypeVariableMarker =
with(resolutionTypeSystemContext) { with(resolutionTypeSystemContext) {
return when (argument) { return when (argument) {
@@ -443,7 +505,10 @@ class PostponedArgumentInputTypesResolver(
private fun getDeclaredParametersConsideringExtensionFunctionsPresence(parameterTypesInfo: ParameterTypesInfo): List<KotlinTypeMarker?>? = private fun getDeclaredParametersConsideringExtensionFunctionsPresence(parameterTypesInfo: ParameterTypesInfo): List<KotlinTypeMarker?>? =
with(parameterTypesInfo) { 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 parametersFromDeclaration
else { else {
val oneLessParameterInDeclarationThanInConstraints = val oneLessParameterInDeclarationThanInConstraints =
@@ -83,6 +83,12 @@ class ClassicConstraintSystemUtilContext(
return atom is FunctionExpression && atom.receiverType != null 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 { override fun createTypeVariableForLambdaReturnType(): TypeVariableMarker {
return TypeVariableForLambdaReturnType( return TypeVariableForLambdaReturnType(
builtIns, builtIns,
@@ -0,0 +1,20 @@
// SKIP_TXT
typealias A = CharSequence.(Int) -> Unit
var w: Int = 1
fun myPrint(x: Int) {}
fun <T> 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) }
)
@@ -0,0 +1,20 @@
// SKIP_TXT
typealias A = CharSequence.(Int) -> Unit
var w: Int = 1
fun myPrint(x: Int) {}
fun <T> select(vararg x: T) = x[0]
val a1: A = select(
{ <!EXPECTED_PARAMETER_TYPE_MISMATCH!>a: Int<!> -> myPrint(a + this.length + 1) },
{ a: Int -> myPrint(a + this.length + 2) }
)
val a2 = select(
{ a: Int -> myPrint(a + this.<!UNRESOLVED_REFERENCE!>length<!> <!DEBUG_INFO_MISSING_UNRESOLVED!>+<!> 1) },
fun CharSequence.(a: Int) { myPrint(a + this.length + 2) },
{ a: Int -> myPrint(a + this.<!UNRESOLVED_REFERENCE!>length<!> <!DEBUG_INFO_MISSING_UNRESOLVED!>+<!> 3) }
)
@@ -0,0 +1,21 @@
// !LANGUAGE: -ConsiderExtensionReceiverFromConstrainsInLambda
// SKIP_TXT
typealias A = CharSequence.(Int) -> Unit
var w: Int = 1
fun myPrint(x: Int) {}
fun <T> 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) }
)
@@ -0,0 +1,21 @@
// !LANGUAGE: -ConsiderExtensionReceiverFromConstrainsInLambda
// SKIP_TXT
typealias A = CharSequence.(Int) -> Unit
var w: Int = 1
fun myPrint(x: Int) {}
fun <T> select(vararg x: T) = x[0]
val a1: A = select(
{ <!EXPECTED_PARAMETER_TYPE_MISMATCH!>a: Int<!> -> myPrint(a + this.length + 1) },
{ a: Int -> myPrint(a + this.length + 2) }
)
val a2 = select(
{ a: Int -> myPrint(a + this.<!UNRESOLVED_REFERENCE!>length<!> <!DEBUG_INFO_MISSING_UNRESOLVED!>+<!> 1) },
fun CharSequence.(a: Int) { myPrint(a + this.length + 2) },
{ a: Int -> myPrint(a + this.<!UNRESOLVED_REFERENCE!>length<!> <!DEBUG_INFO_MISSING_UNRESOLVED!>+<!> 3) }
)
@@ -0,0 +1,22 @@
// !LANGUAGE: +ConsiderExtensionReceiverFromConstrainsInLambda
// FIR_IDENTICAL
// SKIP_TXT
typealias A = CharSequence.(Int) -> Unit
var w: Int = 1
fun myPrint(x: Int) {}
fun <T> 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) }
)
@@ -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) }
}
@@ -13459,12 +13459,36 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/inference/returningLambdaInSuspendContext.kt"); 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 @Test
@TestMetadata("specialCallsWithCallableReferences.kt") @TestMetadata("specialCallsWithCallableReferences.kt")
public void testSpecialCallsWithCallableReferences() throws Exception { public void testSpecialCallsWithCallableReferences() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/specialCallsWithCallableReferences.kt"); 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 @Test
@TestMetadata("starApproximation.kt") @TestMetadata("starApproximation.kt")
public void testStarApproximation() throws Exception { public void testStarApproximation() throws Exception {
@@ -241,6 +241,7 @@ enum class LanguageFeature(
PartiallySpecifiedTypeArguments(KOTLIN_1_7), PartiallySpecifiedTypeArguments(KOTLIN_1_7),
EliminateAmbiguitiesWithExternalTypeParameters(KOTLIN_1_7), EliminateAmbiguitiesWithExternalTypeParameters(KOTLIN_1_7),
EliminateAmbiguitiesOnInheritedSamInterfaces(KOTLIN_1_7), EliminateAmbiguitiesOnInheritedSamInterfaces(KOTLIN_1_7),
ConsiderExtensionReceiverFromConstrainsInLambda(KOTLIN_1_7, kind = BUG_FIX), // KT-49832
// 1.8 // 1.8