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
This commit is contained in:
Denis.Zharkov
2022-11-02 18:51:20 +01:00
committed by Space Team
parent b73acd7a3a
commit ca12cfb90d
8 changed files with 122 additions and 2 deletions
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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<TypeConstructorMarker, VariableWithConstraints>
val fixedTypeVariables: Map<TypeConstructorMarker, KotlinTypeMarker>
val postponedTypeVariables: List<TypeVariableMarker>
val constraintsFromAllForkPoints: MutableList<Pair<IncorporationConstraintPosition, ForkPointData>>
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,
@@ -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<String, String>? {
return comparisonStrings.getValue(x) to
comparisonStrings.getValue(x)
}
@@ -0,0 +1,17 @@
// SKIP_TXT
interface Generic<K, V>
fun <X, Y> Generic<X, Y>.getValue(x: X): Y = TODO()
class MyPair<A, B>(a: A, b: B)
fun <E, F> foo(x: Generic<E, F>, e: E, c: Generic<Int, String>): MyPair<F, F> {
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<String, String>) {}
@@ -0,0 +1,17 @@
// SKIP_TXT
interface Generic<K, V>
fun <X, Y> Generic<X, Y>.getValue(x: X): Y = TODO()
class MyPair<A, B>(a: A, b: B)
fun <E, F> foo(x: Generic<E, F>, e: E, c: Generic<Int, String>): MyPair<F, F> {
if (c === x && e is Int) {
bar(MyPair(<!DEBUG_INFO_SMARTCAST!>x<!>.getValue(<!DEBUG_INFO_SMARTCAST!>e<!>), <!DEBUG_INFO_SMARTCAST!>x<!>.getValue(<!DEBUG_INFO_SMARTCAST!>e<!>)))
return <!TYPE_MISMATCH!>MyPair(<!DEBUG_INFO_SMARTCAST!>x<!>.getValue(<!DEBUG_INFO_SMARTCAST!>e<!>), <!DEBUG_INFO_SMARTCAST!>x<!>.getValue(<!DEBUG_INFO_SMARTCAST!>e<!>))<!>
}
return MyPair(x.getValue(e), x.getValue(e))
}
fun bar(p: MyPair<String, String>) {}
@@ -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 {