wip: equality constraints
diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java
index db345e7..48d7777 100644
--- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java
+++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java
@@ -12607,6 +12607,11 @@
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
}
+ @TestMetadata("interactionWihtIntersectionTypesAndJava.kt")
+ public void testInteractionWihtIntersectionTypesAndJava() throws Exception {
+ runTest("compiler/testData/codegen/box/inference/interactionWihtIntersectionTypesAndJava.kt");
+ }
+
@TestMetadata("kt10822.kt")
public void testKt10822() throws Exception {
runTest("compiler/testData/codegen/box/inference/kt10822.kt");
diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt
index 2dcbce8..5060ebb 100644
--- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt
+++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/AbstractTypeCheckerContextForConstraintSystem.kt
@@ -32,6 +32,8 @@
isFromNullabilityConstraint: Boolean = false
)
+ abstract fun addEqualityConstraint(typeVariable: TypeConstructorMarker, type: KotlinTypeMarker)
+
override fun getLowerCapturedTypePolicy(subType: SimpleTypeMarker, superType: CapturedTypeMarker): LowerCapturedTypePolicy {
return when {
isMyTypeVariable(subType) -> {
diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt
index 20a3674..486e5bc 100644
--- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt
+++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ConstraintInjector.kt
@@ -56,8 +56,52 @@
val typeCheckerContext = TypeCheckerContext(c, IncorporationConstraintPosition(position, initialConstraint))
- addSubTypeConstraintAndIncorporateIt(c, a, b, typeCheckerContext)
- addSubTypeConstraintAndIncorporateIt(c, b, a, typeCheckerContext)
+ with(c) {
+ if (a.isSimpleType() && !a.isMarkedNullable() && a.typeConstructor().isTypeVariable()) {
+ addEqualityConstraintForVariableAndIncorporateIt(c, a, b, typeCheckerContext)
+ } else {
+ addSubTypeConstraintAndIncorporateIt(c, a, b, typeCheckerContext)
+ addSubTypeConstraintAndIncorporateIt(c, b, a, typeCheckerContext)
+ }
+ }
+
+ }
+
+ private fun addEqualityConstraintForVariableAndIncorporateIt(
+ c: Context,
+ typeVariable: KotlinTypeMarker,
+ upperType: KotlinTypeMarker,
+ typeCheckerContext: TypeCheckerContext
+ ) {
+ typeCheckerContext.setConstrainingTypesToPrintDebugInfo(typeVariable, upperType)
+ typeCheckerContext.addEqualityConstraint(typeVariable.typeConstructor(c), upperType)
+
+ while (typeCheckerContext.hasConstraintsToProcess()) {
+ for ((typeVariable, constraint) in typeCheckerContext.extractAllConstraints()!!) {
+ if (c.shouldWeSkipConstraint(typeVariable, constraint)) continue
+
+ val constraints =
+ c.notFixedTypeVariables[typeVariable.freshTypeConstructor(c)] ?: typeCheckerContext.fixedTypeVariable(typeVariable)
+
+ // it is important, that we add constraint here(not inside TypeCheckerContext), because inside incorporation we read constraints
+ constraints.addConstraint(constraint)?.let {
+ if (!constraint.isNullabilityConstraint) {
+ constraintIncorporator.incorporate(typeCheckerContext, typeVariable, it)
+ }
+ }
+ }
+
+ val contextOps = c as? ConstraintSystemOperation
+ if (!typeCheckerContext.hasConstraintsToProcess() ||
+ (contextOps != null && c.notFixedTypeVariables.all { typeVariable ->
+ typeVariable.value.constraints.any { constraint ->
+ constraint.kind == EQUALITY && contextOps.isProperType(constraint.type)
+ }
+ })
+ ) {
+ break
+ }
+ }
}
private fun addSubTypeConstraintAndIncorporateIt(
@@ -102,7 +146,7 @@
}
private fun Context.shouldWeSkipConstraint(typeVariable: TypeVariableMarker, constraint: Constraint): Boolean {
- assert(constraint.kind != EQUALITY)
+// assert(constraint.kind != EQUALITY)
val constraintType = constraint.type
@@ -216,6 +260,10 @@
isFromNullabilityConstraint: Boolean
) = addConstraint(typeVariable, subType, LOWER, isFromNullabilityConstraint)
+ override fun addEqualityConstraint(typeVariable: TypeConstructorMarker, type: KotlinTypeMarker) {
+ addConstraint(typeVariable, type, EQUALITY, false)
+ }
+
private fun isCapturedTypeFromSubtyping(type: KotlinTypeMarker) =
when ((type as? CapturedTypeMarker)?.captureStatus()) {
null, CaptureStatus.FROM_EXPRESSION -> false
diff --git a/compiler/testData/codegen/box/inference/interactionWihtIntersectionTypesAndJava.kt b/compiler/testData/codegen/box/inference/interactionWihtIntersectionTypesAndJava.kt
new file mode 100644
index 0000000..5acc169
--- /dev/null
+++ b/compiler/testData/codegen/box/inference/interactionWihtIntersectionTypesAndJava.kt
@@ -0,0 +1,46 @@
+// FULL_JDK
+// TARGET_BACKEND: JVM
+// WITH_RUNTIME
+
+// FILE: Bag.java
+
+import java.util.*;
+import java.util.function.Supplier;
+
+public class Bag<K, V, C extends E, E extends Collection<V>> {
+ public Bag(Map<K, C> backingMap, Supplier<? extends C> innerCollectionCreator) {
+ // TODO
+ }
+
+ public final void add(K key, V value) {
+ //TODO
+ }
+
+ public static class ListBag<K, V> extends Bag<K, V, List<V>, List<V>> {
+ public ListBag(Map<K, List<V>> backingMap, Supplier<? extends List<V>> innerCollectionCreator) {
+ super(backingMap, innerCollectionCreator);
+ }
+ }
+}
+
+// FILE: test.kt
+
+import java.util.*
+
+fun <K, V, C : E, E : Collection<V>, B : Bag<K, V, C, E>> Iterable<V>.groupByTo(
+ destination: B,
+ keySelector: (V) -> K
+): B = TODO()
+
+enum class Format { Foo, Bar }
+class Instance(val format: Format)
+
+fun test(allInstances: List<Instance>, e: EnumMap<Format, List<Instance>>) {
+ val doesntWork = allInstances.groupByTo(
+ Bag.ListBag(e, ::LinkedList)
+ ) { it.format }
+}
+
+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 469ad6a..7652661 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java
@@ -13832,6 +13832,11 @@
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
}
+ @TestMetadata("interactionWihtIntersectionTypesAndJava.kt")
+ public void testInteractionWihtIntersectionTypesAndJava() throws Exception {
+ runTest("compiler/testData/codegen/box/inference/interactionWihtIntersectionTypesAndJava.kt");
+ }
+
@TestMetadata("kt10822.kt")
public void testKt10822() throws Exception {
runTest("compiler/testData/codegen/box/inference/kt10822.kt");
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java
index 456f567..f96021d 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java
@@ -13832,6 +13832,11 @@
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
}
+ @TestMetadata("interactionWihtIntersectionTypesAndJava.kt")
+ public void testInteractionWihtIntersectionTypesAndJava() throws Exception {
+ runTest("compiler/testData/codegen/box/inference/interactionWihtIntersectionTypesAndJava.kt");
+ }
+
@TestMetadata("kt10822.kt")
public void testKt10822() throws Exception {
runTest("compiler/testData/codegen/box/inference/kt10822.kt");
diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java
index 8b66528..8a4eea6 100644
--- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java
@@ -12607,6 +12607,11 @@
runTest("compiler/testData/codegen/box/inference/integerLiteralTypeInLamdaReturnType.kt");
}
+ @TestMetadata("interactionWihtIntersectionTypesAndJava.kt")
+ public void testInteractionWihtIntersectionTypesAndJava() throws Exception {
+ runTest("compiler/testData/codegen/box/inference/interactionWihtIntersectionTypesAndJava.kt");
+ }
+
@TestMetadata("kt10822.kt")
public void testKt10822() throws Exception {
runTest("compiler/testData/codegen/box/inference/kt10822.kt");