From ca12cfb90d2909285d6ea582685193dbc9916d20 Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Wed, 2 Nov 2022 18:51:20 +0100 Subject: [PATCH] K2: Do not fix variables that has yet unprocessed constraints in forks Otherwise, exception from org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector.TypeCheckerStateForConstraintInjector.fixedTypeVariable might happen during forks resolution The test data is extracted from intelliJ FP test ^KT-43296 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 12 ++++++++++ ...irOldFrontendDiagnosticsTestGenerated.java | 12 ++++++++++ ...DiagnosticsWithLightTreeTestGenerated.java | 12 ++++++++++ .../components/VariableFixationFinder.kt | 24 +++++++++++++++++-- .../forks/nestedCallVariableFixation.kt | 18 ++++++++++++++ .../nestedCallVariableFixationSimple.fir.kt | 17 +++++++++++++ .../forks/nestedCallVariableFixationSimple.kt | 17 +++++++++++++ .../test/runners/DiagnosticTestGenerated.java | 12 ++++++++++ 8 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixation.kt create mode 100644 compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixationSimple.fir.kt create mode 100644 compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixationSimple.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index ba28716f054..968dbc5a5ab 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -15993,6 +15993,18 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/forks"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("nestedCallVariableFixation.kt") + public void testNestedCallVariableFixation() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixation.kt"); + } + + @Test + @TestMetadata("nestedCallVariableFixationSimple.kt") + public void testNestedCallVariableFixationSimple() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixationSimple.kt"); + } + @Test @TestMetadata("overloadResolutionByLambdaReturnTypeAndExpectedType.kt") public void testOverloadResolutionByLambdaReturnTypeAndExpectedType() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index d328e1318c7..abed7d6814a 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -15993,6 +15993,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/forks"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("nestedCallVariableFixation.kt") + public void testNestedCallVariableFixation() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixation.kt"); + } + + @Test + @TestMetadata("nestedCallVariableFixationSimple.kt") + public void testNestedCallVariableFixationSimple() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixationSimple.kt"); + } + @Test @TestMetadata("overloadResolutionByLambdaReturnTypeAndExpectedType.kt") public void testOverloadResolutionByLambdaReturnTypeAndExpectedType() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 4e5a779e522..c94f7bf04d1 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -15993,6 +15993,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/forks"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("nestedCallVariableFixation.kt") + public void testNestedCallVariableFixation() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixation.kt"); + } + + @Test + @TestMetadata("nestedCallVariableFixationSimple.kt") + public void testNestedCallVariableFixationSimple() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixationSimple.kt"); + } + @Test @TestMetadata("overloadResolutionByLambdaReturnTypeAndExpectedType.kt") public void testOverloadResolutionByLambdaReturnTypeAndExpectedType() throws Exception { diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt index 1396f0ea3fb..4f725e3ada8 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt @@ -7,11 +7,13 @@ 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.ForkPointData import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode.PARTIAL import org.jetbrains.kotlin.resolve.calls.inference.hasRecursiveTypeParametersWithGivenSelfType import org.jetbrains.kotlin.resolve.calls.inference.isRecursiveTypeParameter import org.jetbrains.kotlin.resolve.calls.inference.model.Constraint import org.jetbrains.kotlin.resolve.calls.inference.model.DeclaredUpperBoundConstraintPosition +import org.jetbrains.kotlin.resolve.calls.inference.model.IncorporationConstraintPosition import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker import org.jetbrains.kotlin.types.model.* @@ -24,6 +26,8 @@ class VariableFixationFinder( val notFixedTypeVariables: Map val fixedTypeVariables: Map val postponedTypeVariables: List + val constraintsFromAllForkPoints: MutableList> + fun isReified(variable: TypeVariableMarker): Boolean } @@ -65,8 +69,9 @@ class VariableFixationFinder( variable: TypeConstructorMarker, dependencyProvider: TypeVariableDependencyInformationProvider, ): TypeVariableFixationReadiness = when { - !notFixedTypeVariables.contains(variable) || - dependencyProvider.isVariableRelatedToTopLevelType(variable) -> TypeVariableFixationReadiness.FORBIDDEN + !notFixedTypeVariables.contains(variable) || dependencyProvider.isVariableRelatedToTopLevelType(variable) || + variableHasUnprocessedConstraintsInForks(variable) -> + TypeVariableFixationReadiness.FORBIDDEN isTypeInferenceForSelfTypesSupported && areAllProperConstraintsSelfTypeBased(variable) -> TypeVariableFixationReadiness.READY_FOR_FIXATION_DECLARED_UPPER_BOUND_WITH_SELF_TYPES !variableHasProperArgumentConstraints(variable) -> TypeVariableFixationReadiness.WITHOUT_PROPER_ARGUMENT_CONSTRAINT @@ -85,6 +90,21 @@ class VariableFixationFinder( else -> TypeVariableFixationReadiness.READY_FOR_FIXATION } + private fun Context.variableHasUnprocessedConstraintsInForks(variableConstructor: TypeConstructorMarker): Boolean { + if (constraintsFromAllForkPoints.isEmpty()) return false + + for ((_, forkPointData) in constraintsFromAllForkPoints) { + for (constraints in forkPointData) { + for ((typeVariableFromConstraint, constraint) in constraints) { + if (typeVariableFromConstraint.freshTypeConstructor() == variableConstructor) return true + if (containsTypeVariable(constraint.type, variableConstructor)) return true + } + } + } + + return false + } + fun isTypeVariableHasProperConstraint( context: Context, typeVariable: TypeConstructorMarker, diff --git a/compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixation.kt b/compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixation.kt new file mode 100644 index 00000000000..e47019ed96a --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixation.kt @@ -0,0 +1,18 @@ +// SKIP_TXT +// FIR_IDENTICAL +// FULL_JDK +// WITH_STDLIB +// FILE: PyTokenTypes.java +public class PyTokenTypes { + public static final PyTokenTypes LT = new PyTokenTypes(); +} + +// FILE: main.kt +private val comparisonStrings = hashMapOf( + PyTokenTypes.LT to "<", +) + +fun findComparisonNegationOperators(x: PyTokenTypes?): Pair? { + return comparisonStrings.getValue(x) to + comparisonStrings.getValue(x) +} diff --git a/compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixationSimple.fir.kt b/compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixationSimple.fir.kt new file mode 100644 index 00000000000..89b1578f9a6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixationSimple.fir.kt @@ -0,0 +1,17 @@ +// SKIP_TXT +interface Generic + +fun Generic.getValue(x: X): Y = TODO() + +class MyPair(a: A, b: B) + +fun foo(x: Generic, e: E, c: Generic): MyPair { + if (c === x && e is Int) { + bar(MyPair(x.getValue(e), x.getValue(e))) + return MyPair(x.getValue(e), x.getValue(e)) + } + + return MyPair(x.getValue(e), x.getValue(e)) +} + +fun bar(p: MyPair) {} diff --git a/compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixationSimple.kt b/compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixationSimple.kt new file mode 100644 index 00000000000..37fa8e69dc0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixationSimple.kt @@ -0,0 +1,17 @@ +// SKIP_TXT +interface Generic + +fun Generic.getValue(x: X): Y = TODO() + +class MyPair(a: A, b: B) + +fun foo(x: Generic, e: E, c: Generic): MyPair { + if (c === x && e is Int) { + bar(MyPair(x.getValue(e), x.getValue(e))) + return MyPair(x.getValue(e), x.getValue(e)) + } + + return MyPair(x.getValue(e), x.getValue(e)) +} + +fun bar(p: MyPair) {} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index e9075d071ac..9e72e3a4da0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -15999,6 +15999,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/forks"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); } + @Test + @TestMetadata("nestedCallVariableFixation.kt") + public void testNestedCallVariableFixation() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixation.kt"); + } + + @Test + @TestMetadata("nestedCallVariableFixationSimple.kt") + public void testNestedCallVariableFixationSimple() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/forks/nestedCallVariableFixationSimple.kt"); + } + @Test @TestMetadata("overloadResolutionByLambdaReturnTypeAndExpectedType.kt") public void testOverloadResolutionByLambdaReturnTypeAndExpectedType() throws Exception {