From 1624327ba4e4933fabc2633adcafacf3ebca2ff3 Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Fri, 21 Feb 2020 03:00:51 +0300 Subject: [PATCH] [NI] Fix substitution in builder-inference for empty common system --- .../inference/CoroutineInferenceSession.kt | 13 +++-- .../calls/components/InferenceSession.kt | 2 +- .../components/PostponedArgumentsAnalyzer.kt | 4 ++ .../inference/ConstraintSystemBuilder.kt | 1 + .../model/NewConstraintSystemImpl.kt | 4 ++ ...nstraintSystemForCoroutineInferenceCall.kt | 52 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 ++ .../LightAnalysisModeTestGenerated.java | 5 ++ .../ir/FirBlackBoxCodegenTestGenerated.java | 5 ++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 ++ .../IrJsCodegenBoxTestGenerated.java | 5 ++ .../semantics/JsCodegenBoxTestGenerated.java | 5 ++ 12 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt index 9893438e467..ba3726312bc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/inference/CoroutineInferenceSession.kt @@ -105,7 +105,13 @@ class CoroutineInferenceSession( lambda: ResolvedLambdaAtom, initialStorage: ConstraintStorage, diagnosticsHolder: KotlinDiagnosticsHolder - ): Map { + ): Map? { + if (partiallyResolvedCallsInfo.isEmpty() && commonCalls.isEmpty()) { + val emptyCommonSystem = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns) + updateCalls(lambda, emptyCommonSystem) + return null + } + val commonSystem = buildCommonSystem(initialStorage) val context = commonSystem.asConstraintSystemCompleterContext() @@ -281,9 +287,8 @@ class CoroutineInferenceSession( class ComposedSubstitutor(val left: NewTypeSubstitutor, val right: NewTypeSubstitutor) : NewTypeSubstitutor { override fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType? { - return left.substituteNotNullTypeWithConstructor( - right.substituteNotNullTypeWithConstructor(constructor)?.constructor ?: constructor - ) + val rightSubstitution = right.substituteNotNullTypeWithConstructor(constructor) + return left.substituteNotNullTypeWithConstructor(rightSubstitution?.constructor ?: constructor) ?: rightSubstitution } override val isEmpty: Boolean get() = left.isEmpty && right.isEmpty diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/InferenceSession.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/InferenceSession.kt index 95f1c53b96e..8784e366f5b 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/InferenceSession.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/InferenceSession.kt @@ -40,7 +40,7 @@ interface InferenceSession { lambda: ResolvedLambdaAtom, initialStorage: ConstraintStorage, diagnosticsHolder: KotlinDiagnosticsHolder - ): Map + ): Map? fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean fun callCompleted(resolvedAtom: ResolvedAtom): Boolean diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt index c28eadfcb95..4f6bb58d0bd 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt @@ -159,6 +159,10 @@ class PostponedArgumentsAnalyzer( val storageSnapshot = c.getBuilder().currentStorage() val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot, diagnosticHolder) + if (postponedVariables == null) { + c.getBuilder().removePostponedVariables() + return + } for ((constructor, resultType) in postponedVariables) { val variableWithConstraints = storageSnapshot.notFixedTypeVariables[constructor] ?: continue diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt index 24532c5f13f..5f427d3b707 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt @@ -34,6 +34,7 @@ interface ConstraintSystemOperation { fun registerVariable(variable: TypeVariableMarker) fun markPostponedVariable(variable: TypeVariableMarker) fun unmarkPostponedVariable(variable: TypeVariableMarker) + fun removePostponedVariables() fun addSubtypeConstraint(lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker, position: ConstraintPosition) fun addEqualityConstraint(a: KotlinTypeMarker, b: KotlinTypeMarker, position: ConstraintPosition) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt index c7ae669995c..9053dc8167a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt @@ -103,6 +103,10 @@ class NewConstraintSystemImpl( storage.postponedTypeVariables -= variable } + override fun removePostponedVariables() { + storage.postponedTypeVariables.clear() + } + override fun addSubtypeConstraint(lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker, position: ConstraintPosition) = constraintInjector.addInitialSubtypeConstraint( apply { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) }, diff --git a/compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt b/compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt new file mode 100644 index 00000000000..323e354fdad --- /dev/null +++ b/compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt @@ -0,0 +1,52 @@ +// WITH_RUNTIME +// WITH_COROUTINES +// KJS_WITH_FULL_RUNTIME +// IGNORE_BACKEND_FIR: JVM_IR + +import helpers.* +import kotlin.coroutines.* +import kotlin.coroutines.intrinsics.* +import kotlin.experimental.ExperimentalTypeInference + +fun test() { + flow { + emit(1) + }.flatMapLatest { + flow {} + } + + flow { + emit(1) + }.flatMap { + if (it == 1) + flow {} + else + flow {} + } + + flow { + emit(1) + }.flatMap { + if (it == 1) + flow {} + else flow {} + } +} + +fun Flow.flatMap(mapper: suspend (T) -> Flow): Flow = TODO() + +@OptIn(ExperimentalTypeInference::class) +fun flow(@BuilderInference block: suspend FlowCollector.() -> Unit): Flow = TODO() + +@OptIn(ExperimentalTypeInference::class) +inline fun Flow.flatMapLatest(@BuilderInference crossinline transform: suspend (value: T) -> Flow): Flow = TODO() + +interface Flow + +interface FlowCollector { + suspend fun emit(value: T) +} + +fun box(): String { + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index b1524da9158..6a2b6f39cfb 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -6200,6 +6200,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/emptyClosure.kt", "kotlin.coroutines"); } + @TestMetadata("emptyCommonConstraintSystemForCoroutineInferenceCall.kt") + public void testEmptyCommonConstraintSystemForCoroutineInferenceCall() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt"); + } + @TestMetadata("epam.kt") public void testEpam_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/epam.kt", "kotlin.coroutines.experimental"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index fad2a729e21..5d49b7e9c7c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -6200,6 +6200,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/emptyClosure.kt", "kotlin.coroutines"); } + @TestMetadata("emptyCommonConstraintSystemForCoroutineInferenceCall.kt") + public void testEmptyCommonConstraintSystemForCoroutineInferenceCall() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt"); + } + @TestMetadata("epam.kt") public void testEpam_1_2() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/epam.kt", "kotlin.coroutines.experimental"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 12b329d7d58..6461069bde2 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -6080,6 +6080,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/emptyClosure.kt", "kotlin.coroutines"); } + @TestMetadata("emptyCommonConstraintSystemForCoroutineInferenceCall.kt") + public void testEmptyCommonConstraintSystemForCoroutineInferenceCall() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt"); + } + @TestMetadata("epam.kt") public void testEpam_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/epam.kt", "kotlin.coroutines"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 3e33c1e9e27..ba6e0d7969f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -6080,6 +6080,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/emptyClosure.kt", "kotlin.coroutines"); } + @TestMetadata("emptyCommonConstraintSystemForCoroutineInferenceCall.kt") + public void testEmptyCommonConstraintSystemForCoroutineInferenceCall() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt"); + } + @TestMetadata("epam.kt") public void testEpam_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/epam.kt", "kotlin.coroutines"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 0d1e59d7e99..38e2266043b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -5130,6 +5130,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/emptyClosure.kt", "kotlin.coroutines"); } + @TestMetadata("emptyCommonConstraintSystemForCoroutineInferenceCall.kt") + public void testEmptyCommonConstraintSystemForCoroutineInferenceCall() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt"); + } + @TestMetadata("epam.kt") public void testEpam_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/epam.kt", "kotlin.coroutines"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 50c638de47e..437d49f92cf 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -5130,6 +5130,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/emptyClosure.kt", "kotlin.coroutines"); } + @TestMetadata("emptyCommonConstraintSystemForCoroutineInferenceCall.kt") + public void testEmptyCommonConstraintSystemForCoroutineInferenceCall() throws Exception { + runTest("compiler/testData/codegen/box/coroutines/emptyCommonConstraintSystemForCoroutineInferenceCall.kt"); + } + @TestMetadata("epam.kt") public void testEpam_1_3() throws Exception { runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/epam.kt", "kotlin.coroutines");