[FE] Use indexed loop to prevent CME in incorporation
#KT-60225 Fixed
This commit is contained in:
committed by
Space Team
parent
3e41faf91f
commit
3bfcf3090c
+6
@@ -16920,6 +16920,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/inference/receiverTypeMismatch_withoutProper.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveGenericExtensionReceiver.kt")
|
||||
public void testRecursiveGenericExtensionReceiver() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/recursiveGenericExtensionReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
||||
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
||||
|
||||
+6
@@ -16920,6 +16920,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/inference/receiverTypeMismatch_withoutProper.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveGenericExtensionReceiver.kt")
|
||||
public void testRecursiveGenericExtensionReceiver() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/recursiveGenericExtensionReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
||||
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
||||
|
||||
+6
@@ -16914,6 +16914,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/inference/receiverTypeMismatch_withoutProper.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveGenericExtensionReceiver.kt")
|
||||
public void testRecursiveGenericExtensionReceiver() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/recursiveGenericExtensionReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
||||
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
||||
|
||||
+6
@@ -16920,6 +16920,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/inference/receiverTypeMismatch_withoutProper.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveGenericExtensionReceiver.kt")
|
||||
public void testRecursiveGenericExtensionReceiver() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/recursiveGenericExtensionReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
||||
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
||||
|
||||
+13
-3
@@ -27,7 +27,7 @@ class ConstraintIncorporator(
|
||||
// if such type variable is fixed then it is error
|
||||
fun getTypeVariable(typeConstructor: TypeConstructorMarker): TypeVariableMarker?
|
||||
|
||||
fun getConstraintsForVariable(typeVariable: TypeVariableMarker): Collection<Constraint>
|
||||
fun getConstraintsForVariable(typeVariable: TypeVariableMarker): List<Constraint>
|
||||
|
||||
fun addNewIncorporatedConstraint(
|
||||
lowerType: KotlinTypeMarker,
|
||||
@@ -67,7 +67,7 @@ class ConstraintIncorporator(
|
||||
|
||||
// \alpha <: constraint.type
|
||||
if (constraint.kind != ConstraintKind.LOWER) {
|
||||
getConstraintsForVariable(typeVariable).forEach {
|
||||
forEachConstraint(typeVariable) {
|
||||
if (it.kind != ConstraintKind.UPPER) {
|
||||
addNewIncorporatedConstraint(it.type, constraint.type, shouldBeTypeVariableFlexible, it.isNullabilityConstraint)
|
||||
}
|
||||
@@ -76,7 +76,7 @@ class ConstraintIncorporator(
|
||||
|
||||
// constraint.type <: \alpha
|
||||
if (constraint.kind != ConstraintKind.UPPER) {
|
||||
getConstraintsForVariable(typeVariable).forEach {
|
||||
forEachConstraint(typeVariable) {
|
||||
if (it.kind != ConstraintKind.LOWER) {
|
||||
val isFromDeclaredUpperBound =
|
||||
it.position.from is DeclaredUpperBoundConstraintPosition<*> && !it.type.typeConstructor().isTypeVariable()
|
||||
@@ -92,6 +92,16 @@ class ConstraintIncorporator(
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun Context.forEachConstraint(typeVariable: TypeVariableMarker, action: (Constraint) -> Unit) {
|
||||
// We use an indexed loop because the collection might be modified during the iteration.
|
||||
// However, the only modification is appending, so we should be fine.
|
||||
val constraints = getConstraintsForVariable(typeVariable)
|
||||
var i = 0
|
||||
while (i < constraints.size) {
|
||||
action(constraints[i++])
|
||||
}
|
||||
}
|
||||
|
||||
// \alpha <: Number, \beta <: Inv<\alpha> => \beta <: Inv<out Number>
|
||||
private fun Context.insideOtherConstraint(
|
||||
typeVariable: TypeVariableMarker,
|
||||
|
||||
+8
@@ -46,6 +46,14 @@ class MutableVariableWithConstraints private constructor(
|
||||
|
||||
private val mutableConstraints = if (constraints == null) SmartList() else SmartList(constraints)
|
||||
|
||||
/**
|
||||
* The contract for mutating this list is that the only allowed mutation is appending items.
|
||||
* In any other case, it must be set to `null`, so that it will be recomputed when [constraints] is called.
|
||||
*
|
||||
* The reason is that the list might be mutated while it's being iterated.
|
||||
* For this reason, we use an index loop in
|
||||
* [org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintIncorporator.forEachConstraint].
|
||||
*/
|
||||
private var simplifiedConstraints: SmartList<Constraint>? = mutableConstraints
|
||||
|
||||
val rawConstraintsCount get() = mutableConstraints.size
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KT-60225
|
||||
|
||||
class Klass<T: Klass<T>>
|
||||
|
||||
fun <T: Klass<T>> Klass<T>.foo() {}
|
||||
|
||||
fun main() {
|
||||
Klass().foo()
|
||||
}
|
||||
Generated
+6
@@ -16920,6 +16920,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/receiverTypeMismatch_withoutProper.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveGenericExtensionReceiver.kt")
|
||||
public void testRecursiveGenericExtensionReceiver() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/recursiveGenericExtensionReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
||||
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user