diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java index 786e26784cf..75793bb164f 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestWithStdlibGenerated.java @@ -3234,6 +3234,49 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi public void testSuspendFunctions() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/suspendFunctions.kt"); } + + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Performance extends AbstractFirOldFrontendDiagnosticsTestWithStdlib { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInPerformance() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @TestMetadata("reuseBuiltFunctionalTypesForIdLambdas.kt") + public void testReuseBuiltFunctionalTypesForIdLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForIdLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForLambdas.kt") + public void testReuseBuiltFunctionalTypesForLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForPairOfLambdas.kt") + public void testReuseBuiltFunctionalTypesForPairOfLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairOfLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForPairsOfDeepLambdas.kt") + public void testReuseBuiltFunctionalTypesForPairsOfDeepLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas.kt") + public void testReuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForPairsOfIdLambdas.kt") + public void testReuseBuiltFunctionalTypesForPairsOfIdLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfIdLambdas.kt"); + } + } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt index ea7d642e11e..3a5f00f7cdf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt @@ -37,6 +37,7 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) { collectVariablesFromContext: Boolean = false, analyze: (PostponedResolvedAtom) -> Unit ) = with(c) { + val topLevelTypeVariables = candidateReturnType.extractTypeVariables() completion@ while (true) { val postponedArguments = getOrderedNotAnalyzedPostponedArguments(topLevelAtoms) @@ -62,7 +63,11 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) { // Stage 2 val newExpectedTypeWasBuilt = postponedArgumentsInputTypesResolver.collectParameterTypesAndBuildNewExpectedTypes( - asConstraintSystemCompletionContext(), postponedArgumentsWithRevisableType, completionMode, dependencyProvider + asConstraintSystemCompletionContext(), + postponedArgumentsWithRevisableType, + completionMode, + dependencyProvider, + topLevelTypeVariables ) if (newExpectedTypeWasBuilt) diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt index 829167983e5..f940784ef41 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt @@ -17,11 +17,23 @@ interface ConstraintSystemOperation { fun unmarkPostponedVariable(variable: TypeVariableMarker) fun removePostponedVariables() - fun getRevisedVariableForParameter(expectedType: TypeVariableMarker, index: Int): TypeVariableMarker? - fun getRevisedVariableForReturnType(expectedType: TypeVariableMarker): TypeVariableMarker? + fun getBuiltFunctionalExpectedTypeForPostponedArgument( + topLevelVariable: TypeConstructorMarker, + pathToExpectedType: List> + ): KotlinTypeMarker? - fun putRevisedVariableForParameter(expectedType: TypeVariableMarker, index: Int, newVariable: TypeVariableMarker) - fun putRevisedVariableForReturnType(expectedType: TypeVariableMarker, newVariable: TypeVariableMarker) + fun getBuiltFunctionalExpectedTypeForPostponedArgument(expectedTypeVariable: TypeConstructorMarker): KotlinTypeMarker? + + fun putBuiltFunctionalExpectedTypeForPostponedArgument( + topLevelVariable: TypeConstructorMarker, + pathToExpectedType: List>, + builtFunctionalType: KotlinTypeMarker + ) + + fun putBuiltFunctionalExpectedTypeForPostponedArgument( + expectedTypeVariable: TypeConstructorMarker, + builtFunctionalType: KotlinTypeMarker + ) fun addSubtypeConstraint(lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker, position: ConstraintPosition) fun addEqualityConstraint(a: KotlinTypeMarker, b: KotlinTypeMarker, position: ConstraintPosition) 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 a25501a4d12..4fa73b17809 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 @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.utils.SmartSet import org.jetbrains.kotlin.utils.addToStdlib.safeAs +import java.util.* private typealias Context = ConstraintSystemCompletionContext private typealias ResolvedAtomProvider = (TypeVariableMarker) -> Any? @@ -133,48 +134,22 @@ class PostponedArgumentInputTypesResolver( private fun Context.createTypeVariableForReturnType(argument: PostponedAtomWithRevisableExpectedType): TypeVariableMarker = with(resolutionTypeSystemContext) { - val expectedType = argument.expectedType - ?: throw IllegalStateException("Postponed argument's expected type must not be null") - - val variable = getBuilder().currentStorage().allTypeVariables[expectedType.typeConstructor()] - if (variable != null) { - val revisedVariableForReturnType = getBuilder().getRevisedVariableForReturnType(variable) - if (revisedVariableForReturnType != null) return revisedVariableForReturnType - } - return when (argument) { is LambdaWithTypeVariableAsExpectedTypeMarker -> createTypeVariableForLambdaReturnType() is PostponedCallableReferenceMarker -> createTypeVariableForCallableReferenceReturnType() else -> throw IllegalStateException("Unsupported postponed argument type of $argument") - }.also { - if (variable != null) getBuilder().putRevisedVariableForReturnType(variable, it) - - getBuilder().registerVariable(it) - } + }.also { getBuilder().registerVariable(it) } } private fun Context.createTypeVariableForParameterType( argument: PostponedAtomWithRevisableExpectedType, index: Int ): TypeVariableMarker = with(resolutionTypeSystemContext) { - val expectedType = argument.expectedType - ?: throw IllegalStateException("Postponed argument's expected type must not be null") - - val variable = getBuilder().currentStorage().allTypeVariables[expectedType.typeConstructor()] - if (variable != null) { - val revisedVariableForParameter = getBuilder().getRevisedVariableForParameter(variable, index) - if (revisedVariableForParameter != null) return revisedVariableForParameter - } - return when (argument) { is LambdaWithTypeVariableAsExpectedTypeMarker -> createTypeVariableForLambdaParameterType(argument, index) is PostponedCallableReferenceMarker -> createTypeVariableForCallableReferenceParameterType(argument, index) else -> throw IllegalStateException("Unsupported postponed argument type of $argument") - }.also { - if (variable != null) getBuilder().putRevisedVariableForParameter(variable, index, it) - - getBuilder().registerVariable(it) - } + }.also { getBuilder().registerVariable(it) } } private fun Context.createTypeVariablesForParameters( @@ -243,14 +218,73 @@ class PostponedArgumentInputTypesResolver( } } + private fun Context.computeTypeVariablePathInsideGivenType( + type: KotlinTypeMarker, + targetVariable: TypeConstructorMarker, + path: Stack> = Stack() + ): List>? { + val typeConstructor = type.typeConstructor() + + if (typeConstructor == targetVariable) + return emptyList() + + for (i in 0 until type.argumentsCount()) { + val argumentType = type.getArgument(i).getType() + + if (argumentType.typeConstructor() == targetVariable) { + return path.toList() + (typeConstructor to i) + } else if (argumentType.argumentsCount() != 0) { + path.push(typeConstructor to i) + computeTypeVariablePathInsideGivenType(argumentType, targetVariable, path)?.let { return it } + path.pop() + } + } + + return null + } + + private fun Context.selectFirstRelatedVariable( + variables: Set, + targetVariable: TypeConstructorMarker, + variableDependencyProvider: TypeVariableDependencyInformationProvider + ): TypeVariableTypeConstructorMarker? { + val relatedVariables = variableDependencyProvider.getDeeplyDependentVariables(targetVariable).orEmpty() + + variableDependencyProvider.getShallowlyDependentVariables(targetVariable) + + return variables.firstOrNull { it in relatedVariables && it in notFixedTypeVariables } + } + private fun Context.buildNewFunctionalExpectedType( argument: PostponedAtomWithRevisableExpectedType, - parameterTypesInfo: ParameterTypesInfo + parameterTypesInfo: ParameterTypesInfo, + variableDependencyProvider: TypeVariableDependencyInformationProvider, + topLevelTypeVariables: Set ): KotlinTypeMarker? = with(resolutionTypeSystemContext) { - val expectedType = argument.expectedType + val expectedType = argument.expectedType ?: return null + val expectedTypeConstructor = expectedType.typeConstructor() - if (expectedType == null || expectedType.typeConstructor() !in notFixedTypeVariables) - return null + if (expectedTypeConstructor !in notFixedTypeVariables) return null + + val relatedTopLevelVariable = selectFirstRelatedVariable(topLevelTypeVariables, expectedTypeConstructor, variableDependencyProvider) + val pathFromRelatedTopLevelVariable = if (relatedTopLevelVariable != null) { + val constraintTypes = notFixedTypeVariables.getValue(relatedTopLevelVariable).constraints.map { it.type }.toSet() + val containingType = constraintTypes.find { constraintType -> + constraintType.contains { it.typeConstructor() == expectedTypeConstructor } + } + if (containingType != null) { + computeTypeVariablePathInsideGivenType(containingType, expectedTypeConstructor) + } else null + } else null + + if (pathFromRelatedTopLevelVariable != null && relatedTopLevelVariable != null) { + // try to take from the cache of functional types by paths from a top level type variable + getBuilder().getBuiltFunctionalExpectedTypeForPostponedArgument(relatedTopLevelVariable, pathFromRelatedTopLevelVariable) + ?.let { return it } + } else { + // try to take from the cache of functional types by expected types + getBuilder().getBuiltFunctionalExpectedTypeForPostponedArgument(expectedTypeConstructor) + ?.let { return it } + } val parametersFromConstraints = parameterTypesInfo.parametersFromConstraints val parametersFromDeclaration = getDeclaredParametersConsideringExtensionFunctionsPresence(parameterTypesInfo) @@ -319,6 +353,12 @@ class PostponedArgumentInputTypesResolver( createArgumentConstraintPosition(argument) ) + if (pathFromRelatedTopLevelVariable != null && relatedTopLevelVariable != null) { + getBuilder().putBuiltFunctionalExpectedTypeForPostponedArgument(relatedTopLevelVariable, pathFromRelatedTopLevelVariable, newExpectedType) + } else { + getBuilder().putBuiltFunctionalExpectedTypeForPostponedArgument(expectedTypeConstructor, newExpectedType) + } + return newExpectedType } @@ -326,7 +366,8 @@ class PostponedArgumentInputTypesResolver( c: Context, postponedArguments: List, completionMode: ConstraintSystemCompletionMode, - dependencyProvider: TypeVariableDependencyInformationProvider + dependencyProvider: TypeVariableDependencyInformationProvider, + topLevelTypeVariables: Set ): Boolean = with(resolutionTypeSystemContext) { // We can collect parameter types from declaration in any mode, they can't change during completion. for (argument in postponedArguments) { @@ -349,7 +390,7 @@ class PostponedArgumentInputTypesResolver( val parameterTypesInfo = c.extractParameterTypesInfo(argument, postponedArguments, dependencyProvider) ?: return@any false val newExpectedType = - c.buildNewFunctionalExpectedType(argument, parameterTypesInfo) ?: return@any false + c.buildNewFunctionalExpectedType(argument, parameterTypesInfo, dependencyProvider, topLevelTypeVariables) ?: return@any false argument.reviseExpectedType(newExpectedType) diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt index 08af630f290..bce889f6a9c 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt @@ -39,8 +39,8 @@ interface ConstraintStorage { val hasContradiction: Boolean val fixedTypeVariables: Map val postponedTypeVariables: List - val revisedVariablesForParameters: Map, TypeVariableMarker> - val revisedReturnTypes: Map + val builtFunctionalTypesForPostponedArgumentsByTopLevelTypeVariables: Map>>, KotlinTypeMarker> + val builtFunctionalTypesForPostponedArgumentsByExpectedTypeVariables: Map object Empty : ConstraintStorage { override val allTypeVariables: Map get() = emptyMap() @@ -51,8 +51,8 @@ interface ConstraintStorage { override val hasContradiction: Boolean get() = false override val fixedTypeVariables: Map get() = emptyMap() override val postponedTypeVariables: List get() = emptyList() - override val revisedVariablesForParameters: Map, TypeVariableMarker> = emptyMap() - override val revisedReturnTypes: Map = emptyMap() + override val builtFunctionalTypesForPostponedArgumentsByTopLevelTypeVariables: Map>>, KotlinTypeMarker> = emptyMap() + override val builtFunctionalTypesForPostponedArgumentsByExpectedTypeVariables: Map = emptyMap() } } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt index f2f85baac89..2f64e909349 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt @@ -202,6 +202,8 @@ internal class MutableConstraintStorage : ConstraintStorage { override val hasContradiction: Boolean get() = errors.any { !it.applicability.isSuccess } override val fixedTypeVariables: MutableMap = LinkedHashMap() override val postponedTypeVariables: MutableList = SmartList() - override val revisedVariablesForParameters: MutableMap, TypeVariableMarker> = LinkedHashMap() - override val revisedReturnTypes: MutableMap = LinkedHashMap() + override val builtFunctionalTypesForPostponedArgumentsByTopLevelTypeVariables: MutableMap>>, KotlinTypeMarker> = + LinkedHashMap() + override val builtFunctionalTypesForPostponedArgumentsByExpectedTypeVariables: MutableMap = + LinkedHashMap() } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt index fdfd8bf9f42..fd4527e34ad 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt @@ -115,21 +115,28 @@ class NewConstraintSystemImpl( storage.postponedTypeVariables.clear() } - override fun getRevisedVariableForParameter(expectedType: TypeVariableMarker, index: Int): TypeVariableMarker? { - return storage.revisedVariablesForParameters[expectedType to index] + override fun putBuiltFunctionalExpectedTypeForPostponedArgument( + topLevelVariable: TypeConstructorMarker, + pathToExpectedType: List>, + builtFunctionalType: KotlinTypeMarker + ) { + storage.builtFunctionalTypesForPostponedArgumentsByTopLevelTypeVariables[topLevelVariable to pathToExpectedType] = builtFunctionalType } - override fun getRevisedVariableForReturnType(expectedType: TypeVariableMarker): TypeVariableMarker? { - return storage.revisedReturnTypes[expectedType] + override fun putBuiltFunctionalExpectedTypeForPostponedArgument( + expectedTypeVariable: TypeConstructorMarker, + builtFunctionalType: KotlinTypeMarker + ) { + storage.builtFunctionalTypesForPostponedArgumentsByExpectedTypeVariables[expectedTypeVariable] = builtFunctionalType } - override fun putRevisedVariableForParameter(expectedType: TypeVariableMarker, index: Int, newVariable: TypeVariableMarker) { - storage.revisedVariablesForParameters[expectedType to index] = newVariable - } + override fun getBuiltFunctionalExpectedTypeForPostponedArgument( + topLevelVariable: TypeConstructorMarker, + pathToExpectedType: List> + ) = storage.builtFunctionalTypesForPostponedArgumentsByTopLevelTypeVariables[topLevelVariable to pathToExpectedType] - override fun putRevisedVariableForReturnType(expectedType: TypeVariableMarker, newVariable: TypeVariableMarker) { - storage.revisedReturnTypes[expectedType] = newVariable - } + override fun getBuiltFunctionalExpectedTypeForPostponedArgument(expectedTypeVariable: TypeConstructorMarker) = + storage.builtFunctionalTypesForPostponedArgumentsByExpectedTypeVariables[expectedTypeVariable] override fun addSubtypeConstraint(lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker, position: ConstraintPosition) = constraintInjector.addInitialSubtypeConstraint( diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt index 8cd0ef22580..cbd0cb02edb 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/KotlinConstraintSystemCompleter.kt @@ -66,6 +66,8 @@ class KotlinConstraintSystemCompleter( collectVariablesFromContext: Boolean, analyze: (PostponedResolvedAtom) -> Unit ) { + val topLevelTypeVariables = topLevelType.extractTypeVariables() + completion@ while (true) { // TODO val postponedArguments = getOrderedNotAnalyzedPostponedArguments(topLevelAtoms) @@ -89,7 +91,11 @@ class KotlinConstraintSystemCompleter( // Stage 2: collect parameter types for postponed arguments val wasBuiltNewExpectedTypeForSomeArgument = postponedArgumentInputTypesResolver.collectParameterTypesAndBuildNewExpectedTypes( - asConstraintSystemCompletionContext(), postponedArgumentsWithRevisableType, completionMode, dependencyProvider + asConstraintSystemCompletionContext(), + postponedArgumentsWithRevisableType, + completionMode, + dependencyProvider, + topLevelTypeVariables ) if (wasBuiltNewExpectedTypeForSomeArgument) diff --git a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt index a5d809a3cd3..a8516c5a43e 100644 --- a/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/basic.fir.kt @@ -143,7 +143,7 @@ fun main() { // Resolution of extension/non-extension functions combination val x19: String.() -> Unit = select(")!>id { this }, ")!>id(fun(x: String) {})) - val x20: String.() -> Unit = select(")!>{ this }, (fun(x: String) {})) + val x20: String.() -> Unit = select(")!>{ this }, (fun(x: String) {})) val x21: String.() -> Unit = select(")!>id(fun(x: String) {}), ")!>id(fun(x: String) {})) select(id Unit>(fun(x: String) {}), ")!>id(fun(x: String) {})) select(")!>id(fun String.(x: String) {}), ")!>id(fun(x: String, y: String) {})) diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForIdLambdas.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForIdLambdas.kt new file mode 100644 index 00000000000..e39c5eedc5e --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForIdLambdas.kt @@ -0,0 +1,40 @@ +// FIR_IDENTICAL +// SKIP_TXT +// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER + +fun id(x: T) = x + +class A { + val x: Map Unit> = + mapOf( + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> }, + "" to id { a, b, c, d -> } + ) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForLambdas.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForLambdas.kt new file mode 100644 index 00000000000..42c26a279b2 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForLambdas.kt @@ -0,0 +1,38 @@ +// FIR_IDENTICAL +// SKIP_TXT +// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER + +class A { + val x: Map Unit> = + mapOf( + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> }, + "" to { a, b, c, d -> } + ) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairOfLambdas.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairOfLambdas.kt new file mode 100644 index 00000000000..477e9416603 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairOfLambdas.kt @@ -0,0 +1,42 @@ +// FIR_IDENTICAL +// SKIP_TXT +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -CAST_NEVER_SUCCEEDS + +interface Foo {} + +fun fooOf(vararg pairs: Pair) = null as Foo + +fun to(th: A, that: B): Pair = Pair(th, that) + +class A { + val x: Foo<(Int, String, String, String) -> Unit, (String, String, String, String) -> Unit> = + fooOf( + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + to({ a, b, c, d -> }, { a, b, c, d -> }), + ) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepLambdas.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepLambdas.kt new file mode 100644 index 00000000000..0c543f024a3 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepLambdas.kt @@ -0,0 +1,46 @@ +// FIR_IDENTICAL +// SKIP_TXT +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -CAST_NEVER_SUCCEEDS + +fun id(x: T) = x + +interface Foo {} + +fun fooOf(vararg pairs: Pair) = null as Foo + +fun to(th: A, that: B): Pair = Pair(th, that) + +class Inv(x: K) + +class A { + val x: Foo Unit>, Inv<(String, String, String, String) -> Unit>> = + fooOf( + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + to(Inv { a -> }, Inv { a, b, c, d -> }), + ) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas.kt new file mode 100644 index 00000000000..32724beffff --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas.kt @@ -0,0 +1,48 @@ +// FIR_IDENTICAL +// SKIP_TXT +// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER -UNUSED_PARAMETER -CAST_NEVER_SUCCEEDS + +fun id(x: T) = x + +interface Foo {} + +fun fooOf(vararg pairs: Pair) = null as Foo + +fun to(th: A, that: B): Pair = Pair(th, that) + +class Inv(x: K) + +fun Unit> take(x: A, y: A) = null as (Int, String, String, String) -> Unit + +class A { + val x: Foo Unit>, Inv<(Int, String, String, String) -> Unit>> = + fooOf( + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv(take({ a, b, c, d -> }, { a, b, c, d -> }))), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv(take({ a, b, c, d -> }, { a, b, c, d -> }))), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv(take({ a, b, c, d -> }, { a, b, c, d -> }))), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv(take({ a, b, c, d -> }, { a, b, c, d -> }))), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv(take({ a, b, c, d -> }, { a, b, c, d -> }))), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + to(Inv(take({ a, b, c, d -> }, { a, b, c, d -> })), Inv { a, b, c, d -> }), + ) +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfIdLambdas.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfIdLambdas.kt new file mode 100644 index 00000000000..3f13812bc27 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfIdLambdas.kt @@ -0,0 +1,44 @@ +// FIR_IDENTICAL +// SKIP_TXT +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -CAST_NEVER_SUCCEEDS + +fun id(x: T) = x + +interface Foo {} + +fun fooOf(vararg pairs: Pair) = null as Foo + +fun to(th: A, that: B): Pair = Pair(th, that) + +class A { + val x: Foo<(Int, String, String, String) -> Unit, (String, String, String, String) -> Unit> = + fooOf( + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + to(id { a, b, c, d -> }, id { a, b, c, d -> }), + ) +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index f6e18fd621c..c303f7d0e02 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -3384,6 +3384,49 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW public void testSuspendFunctions() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/suspendFunctions.kt"); } + + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Performance extends AbstractDiagnosticsTestWithStdLib { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInPerformance() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @TestMetadata("reuseBuiltFunctionalTypesForIdLambdas.kt") + public void testReuseBuiltFunctionalTypesForIdLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForIdLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForLambdas.kt") + public void testReuseBuiltFunctionalTypesForLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForPairOfLambdas.kt") + public void testReuseBuiltFunctionalTypesForPairOfLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairOfLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForPairsOfDeepLambdas.kt") + public void testReuseBuiltFunctionalTypesForPairsOfDeepLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas.kt") + public void testReuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForPairsOfIdLambdas.kt") + public void testReuseBuiltFunctionalTypesForPairsOfIdLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfIdLambdas.kt"); + } + } } } diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index 47f18944933..14948d93328 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -3384,6 +3384,49 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno public void testSuspendFunctions() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/suspendFunctions.kt"); } + + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Performance extends AbstractDiagnosticsTestWithStdLibUsingJavac { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInPerformance() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @TestMetadata("reuseBuiltFunctionalTypesForIdLambdas.kt") + public void testReuseBuiltFunctionalTypesForIdLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForIdLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForLambdas.kt") + public void testReuseBuiltFunctionalTypesForLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForPairOfLambdas.kt") + public void testReuseBuiltFunctionalTypesForPairOfLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairOfLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForPairsOfDeepLambdas.kt") + public void testReuseBuiltFunctionalTypesForPairsOfDeepLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas.kt") + public void testReuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas.kt"); + } + + @TestMetadata("reuseBuiltFunctionalTypesForPairsOfIdLambdas.kt") + public void testReuseBuiltFunctionalTypesForPairsOfIdLambdas() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfIdLambdas.kt"); + } + } } } diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index 37935eaf548..d6bd8ab2765 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -7,6 +7,8 @@ package org.jetbrains.kotlin.types.model import org.jetbrains.kotlin.types.AbstractTypeCheckerContext import org.jetbrains.kotlin.types.Variance +import java.util.* +import kotlin.collections.ArrayList import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract @@ -207,6 +209,25 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui fun getFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker fun getKFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker + + private fun KotlinTypeMarker.extractTypeVariables(to: MutableSet) { + for (i in 0 until argumentsCount()) { + val argument = getArgument(i) + + if (argument.isStarProjection()) continue + + val argumentType = argument.getType() + val argumentTypeConstructor = argumentType.typeConstructor() + if (argumentTypeConstructor is TypeVariableTypeConstructorMarker) { + to.add(argumentTypeConstructor) + } else if (argumentType.argumentsCount() != 0) { + argumentType.extractTypeVariables(to) + } + } + } + + @OptIn(ExperimentalStdlibApi::class) + fun KotlinTypeMarker.extractTypeVariables() = buildSet { extractTypeVariables(this) } }