[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");
|
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
|
@Test
|
||||||
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
||||||
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
||||||
|
|||||||
+6
@@ -16920,6 +16920,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/receiverTypeMismatch_withoutProper.kt");
|
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
|
@Test
|
||||||
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
||||||
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
||||||
|
|||||||
+6
@@ -16914,6 +16914,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/receiverTypeMismatch_withoutProper.kt");
|
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
|
@Test
|
||||||
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
||||||
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
||||||
|
|||||||
+6
@@ -16920,6 +16920,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/receiverTypeMismatch_withoutProper.kt");
|
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
|
@Test
|
||||||
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
||||||
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
||||||
|
|||||||
+13
-3
@@ -27,7 +27,7 @@ class ConstraintIncorporator(
|
|||||||
// if such type variable is fixed then it is error
|
// if such type variable is fixed then it is error
|
||||||
fun getTypeVariable(typeConstructor: TypeConstructorMarker): TypeVariableMarker?
|
fun getTypeVariable(typeConstructor: TypeConstructorMarker): TypeVariableMarker?
|
||||||
|
|
||||||
fun getConstraintsForVariable(typeVariable: TypeVariableMarker): Collection<Constraint>
|
fun getConstraintsForVariable(typeVariable: TypeVariableMarker): List<Constraint>
|
||||||
|
|
||||||
fun addNewIncorporatedConstraint(
|
fun addNewIncorporatedConstraint(
|
||||||
lowerType: KotlinTypeMarker,
|
lowerType: KotlinTypeMarker,
|
||||||
@@ -67,7 +67,7 @@ class ConstraintIncorporator(
|
|||||||
|
|
||||||
// \alpha <: constraint.type
|
// \alpha <: constraint.type
|
||||||
if (constraint.kind != ConstraintKind.LOWER) {
|
if (constraint.kind != ConstraintKind.LOWER) {
|
||||||
getConstraintsForVariable(typeVariable).forEach {
|
forEachConstraint(typeVariable) {
|
||||||
if (it.kind != ConstraintKind.UPPER) {
|
if (it.kind != ConstraintKind.UPPER) {
|
||||||
addNewIncorporatedConstraint(it.type, constraint.type, shouldBeTypeVariableFlexible, it.isNullabilityConstraint)
|
addNewIncorporatedConstraint(it.type, constraint.type, shouldBeTypeVariableFlexible, it.isNullabilityConstraint)
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ class ConstraintIncorporator(
|
|||||||
|
|
||||||
// constraint.type <: \alpha
|
// constraint.type <: \alpha
|
||||||
if (constraint.kind != ConstraintKind.UPPER) {
|
if (constraint.kind != ConstraintKind.UPPER) {
|
||||||
getConstraintsForVariable(typeVariable).forEach {
|
forEachConstraint(typeVariable) {
|
||||||
if (it.kind != ConstraintKind.LOWER) {
|
if (it.kind != ConstraintKind.LOWER) {
|
||||||
val isFromDeclaredUpperBound =
|
val isFromDeclaredUpperBound =
|
||||||
it.position.from is DeclaredUpperBoundConstraintPosition<*> && !it.type.typeConstructor().isTypeVariable()
|
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>
|
// \alpha <: Number, \beta <: Inv<\alpha> => \beta <: Inv<out Number>
|
||||||
private fun Context.insideOtherConstraint(
|
private fun Context.insideOtherConstraint(
|
||||||
typeVariable: TypeVariableMarker,
|
typeVariable: TypeVariableMarker,
|
||||||
|
|||||||
+8
@@ -46,6 +46,14 @@ class MutableVariableWithConstraints private constructor(
|
|||||||
|
|
||||||
private val mutableConstraints = if (constraints == null) SmartList() else SmartList(constraints)
|
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
|
private var simplifiedConstraints: SmartList<Constraint>? = mutableConstraints
|
||||||
|
|
||||||
val rawConstraintsCount get() = mutableConstraints.size
|
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");
|
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
|
@Test
|
||||||
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
||||||
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user