Fix inference for lambdas with with extension function expected type
^KT-49832 Fixed ^KT-49836 Fixed
This commit is contained in:
committed by
teamcityserver
parent
3fb17cfa9a
commit
0d9ad62d4a
+24
@@ -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 {
|
||||||
|
|||||||
+24
@@ -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 {
|
||||||
|
|||||||
+24
@@ -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 {
|
||||||
|
|||||||
+8
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -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()
|
||||||
|
|
||||||
|
|||||||
+3
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
+80
-15
@@ -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 =
|
||||||
@@ -529,4 +594,4 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
const val TYPE_VARIABLE_NAME_PREFIX_FOR_CR_PARAMETER_TYPE = "_QP"
|
const val TYPE_VARIABLE_NAME_PREFIX_FOR_CR_PARAMETER_TYPE = "_QP"
|
||||||
const val TYPE_VARIABLE_NAME_FOR_CR_RETURN_TYPE = "_Q"
|
const val TYPE_VARIABLE_NAME_FOR_CR_RETURN_TYPE = "_Q"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -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,
|
||||||
|
|||||||
+20
@@ -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) }
|
||||||
|
)
|
||||||
+21
@@ -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) }
|
||||||
|
)
|
||||||
+21
@@ -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) }
|
||||||
|
)
|
||||||
+22
@@ -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) }
|
||||||
|
}
|
||||||
Generated
+24
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user