From ac7fddaad5086fae4d05006559570dd50f57687e Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 28 Nov 2022 17:54:55 +0200 Subject: [PATCH] [FE] Always infer upper types to intersection types in K2... ...and always use old algorithm for K1 ^KT-51221 --- .../kotlin/fir/types/ConeInferenceContext.kt | 3 +++ .../inference/components/ResultTypeResolver.kt | 8 ++------ .../constraintOnFunctionLiteral.fir.kt | 2 +- .../emptyIntersectionTypes/kt45461_25.diag.txt | 9 ++++++++- .../emptyIntersectionTypes/kt45461_25.kt | 2 +- .../emptyIntersectionTypes/kt45461_26.diag.txt | 8 +++++++- .../emptyIntersectionTypes/kt45461_26.kt | 2 +- .../inference/expectedTypeWithGenerics.fir.kt | 2 +- .../specialConstructions/exclExclAsCall.fir.kt | 2 +- ...ontIntersectUpperBoundWithExpectedType.fir.kt | 4 ++-- .../tests/typeParameters/kt42472.fir.kt | 2 +- .../tests/typeParameters/kt46186.fir.kt | 16 ++++++++-------- .../annotationsForResolve/exactAnnotation.fir.kt | 2 +- .../kotlin/types/model/TypeSystemContext.kt | 2 ++ .../types/checker/ClassicTypeSystemContext.kt | 3 +++ 15 files changed, 42 insertions(+), 25 deletions(-) diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt index 7dc42d09272..b7ac821d368 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt @@ -577,4 +577,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo override fun createSubstitutorForSuperTypes(baseType: KotlinTypeMarker): TypeSubstitutorMarker? = if (baseType is ConeLookupTagBasedType) createSubstitutionForSupertype(baseType, session) else null + + override val isK2: Boolean + get() = true } diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt index 4443d46ae7f..3bc2b973d89 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt @@ -241,12 +241,8 @@ class ResultTypeResolver( } private fun Context.computeUpperType(upperConstraints: List): KotlinTypeMarker { - val isInferringIntoEmptyIntersectionEnabled = - languageVersionSettings.supportsFeature(LanguageFeature.ForbidInferringTypeVariablesIntoEmptyIntersection) - - // TODO: Remove this after stopping support of disabling `ForbidInferringTypeVariablesIntoEmptyIntersection` - // If `ForbidInferringTypeVariablesIntoEmptyIntersection` is enabled, we do the corresponding checks during resolution and completion - return if (!isInferringIntoEmptyIntersectionEnabled) { + // TODO: Remove this after stopping support of K1 + return if (!isK2) { val intersectionUpperType = intersectTypes(upperConstraints.map { it.type }) val resultIsActuallyIntersection = intersectionUpperType.typeConstructor().isIntersection() diff --git a/compiler/testData/diagnostics/tests/inference/constraints/constraintOnFunctionLiteral.fir.kt b/compiler/testData/diagnostics/tests/inference/constraints/constraintOnFunctionLiteral.fir.kt index 42f8f9b9907..e07cf77a18f 100644 --- a/compiler/testData/diagnostics/tests/inference/constraints/constraintOnFunctionLiteral.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/constraints/constraintOnFunctionLiteral.fir.kt @@ -2,7 +2,7 @@ package c import java.util.ArrayList -fun Array.toIntArray(): IntArray = this.mapTo(IntArray(size), {it}) +fun Array.toIntArray(): IntArray = this.mapTo(IntArray(size), {it}) fun Array.toArrayList(): ArrayList = this.mapTo(ArrayList(size), {it}) diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_25.diag.txt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_25.diag.txt index ce17a845c9c..8d1445c204f 100644 --- a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_25.diag.txt +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_25.diag.txt @@ -1,3 +1,10 @@ -/kt45461_25.kt:11:34: error: type argument for a type parameter S can't be inferred because it has incompatible upper bounds: String, K, Float (multiple incompatible classes: String, Int) +/kt45461_25.kt:11:20: error: type mismatch: inferred type is {K & String} but Float was expected + val x: Float = Bar().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 + ^ +/kt45461_25.kt:11:34: error: type argument for a type parameter S can't be inferred because it has incompatible upper bounds: String, K (multiple incompatible classes: String, Int) val x: Float = Bar().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 ^ +/kt45461_25.kt:11:34: error: type mismatch: inferred type is {K & String} but Float was expected + val x: Float = Bar().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 + ^ + diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_25.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_25.kt index c41a044445b..fcd114aea8e 100644 --- a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_25.kt +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_25.kt @@ -8,5 +8,5 @@ class Bar { fun Int> main() { val foo = Foo() - val x: Float = Bar().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 + val x: Float = Bar().takeFoo(foo) // error in 1.3.72, no error in 1.4.31 } diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_26.diag.txt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_26.diag.txt index e524b415033..6179b9bc695 100644 --- a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_26.diag.txt +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_26.diag.txt @@ -1,4 +1,10 @@ -/kt45461_26.kt:13:44: error: type argument for a type parameter S can't be inferred because it has incompatible upper bounds: Out, K, Out (multiple incompatible classes: String, Int) +/kt45461_26.kt:13:25: error: type mismatch: inferred type is {K & Out} but Out was expected + val x: Out = Bar>().takeFoo(foo) + ^ +/kt45461_26.kt:13:44: error: type argument for a type parameter S can't be inferred because it has incompatible upper bounds: Out, K (multiple incompatible classes: String, Int) + val x: Out = Bar>().takeFoo(foo) + ^ +/kt45461_26.kt:13:44: error: type mismatch: inferred type is {K & Out} but Out was expected val x: Out = Bar>().takeFoo(foo) ^ diff --git a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_26.kt b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_26.kt index 2f887847a81..5e7b3bfab00 100644 --- a/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_26.kt +++ b/compiler/testData/diagnostics/tests/inference/emptyIntersectionTypes/kt45461_26.kt @@ -10,5 +10,5 @@ class Out fun Out> main() { val foo = Foo() - val x: Out = Bar>()., K, Out; multiple incompatible classes; : String, Int")!>takeFoo(foo) + val x: Out = Bar>()., K; multiple incompatible classes; : String, Int"), TYPE_MISMATCH!>takeFoo(foo) } diff --git a/compiler/testData/diagnostics/tests/inference/expectedTypeWithGenerics.fir.kt b/compiler/testData/diagnostics/tests/inference/expectedTypeWithGenerics.fir.kt index 01f06e0c623..221ff40955f 100644 --- a/compiler/testData/diagnostics/tests/inference/expectedTypeWithGenerics.fir.kt +++ b/compiler/testData/diagnostics/tests/inference/expectedTypeWithGenerics.fir.kt @@ -11,7 +11,7 @@ fun test(x: X) { fun g() { fun foo(): T = TODO() - val y = foo() as Int + val y = foo() as Int val y2 = foo() as D } diff --git a/compiler/testData/diagnostics/tests/resolve/specialConstructions/exclExclAsCall.fir.kt b/compiler/testData/diagnostics/tests/resolve/specialConstructions/exclExclAsCall.fir.kt index 5e327ec4a2b..3ae10331923 100644 --- a/compiler/testData/diagnostics/tests/resolve/specialConstructions/exclExclAsCall.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/specialConstructions/exclExclAsCall.fir.kt @@ -13,7 +13,7 @@ fun emptyNullableListOfA(): List? = null fun testExclExcl() { doList(emptyNullableListOfA()!!) //should be an error here - val l: List = id(emptyNullableListOfA()!!) + val l: List = ")!>id(emptyNullableListOfA()!!) doList(strangeNullableList { doInt(it) }!!) //lambda should be analyzed (at completion phase) } diff --git a/compiler/testData/diagnostics/tests/typeParameters/dontIntersectUpperBoundWithExpectedType.fir.kt b/compiler/testData/diagnostics/tests/typeParameters/dontIntersectUpperBoundWithExpectedType.fir.kt index bb80323465a..2e1098043f3 100644 --- a/compiler/testData/diagnostics/tests/typeParameters/dontIntersectUpperBoundWithExpectedType.fir.kt +++ b/compiler/testData/diagnostics/tests/typeParameters/dontIntersectUpperBoundWithExpectedType.fir.kt @@ -9,9 +9,9 @@ fun foo(): T? { } fun main() { - val a: Bar? = foo() + val a: Bar? = foo() } fun wtf(): T = TODO() -val bar: Int = wtf() // happily compiles +val bar: Int = wtf() // happily compiles diff --git a/compiler/testData/diagnostics/tests/typeParameters/kt42472.fir.kt b/compiler/testData/diagnostics/tests/typeParameters/kt42472.fir.kt index d0ea0f7d911..d57e1595b87 100644 --- a/compiler/testData/diagnostics/tests/typeParameters/kt42472.fir.kt +++ b/compiler/testData/diagnostics/tests/typeParameters/kt42472.fir.kt @@ -7,6 +7,6 @@ fun interface ReadOnlyProperty { } class Problem { - val variable: Int by delegate() // delegate returns `ReadOnlyProperty` + val variable: Int by delegate() // delegate returns `ReadOnlyProperty` fun delegate() = null as ReadOnlyProperty } diff --git a/compiler/testData/diagnostics/tests/typeParameters/kt46186.fir.kt b/compiler/testData/diagnostics/tests/typeParameters/kt46186.fir.kt index 06f37cb6505..4631cbf5291 100644 --- a/compiler/testData/diagnostics/tests/typeParameters/kt46186.fir.kt +++ b/compiler/testData/diagnostics/tests/typeParameters/kt46186.fir.kt @@ -9,13 +9,13 @@ abstract class View4 interface View5 fun findViewById1(): T = null as T -fun test1(): I = findViewById1() +fun test1(): I = findViewById1() fun findViewById2(): T = null as T fun test2(): I = findViewById2() inline fun findViewById3(): T = null as T -fun test3(): I = findViewById3() +fun test3(): I = findViewById3() inline fun findViewById4(): T = null as T fun test4(): I = findViewById4() @@ -39,17 +39,17 @@ inline fun findViewById10(): T where T: View3, T: View5 = null as T fun test10(): I = findViewById10() fun findViewById11(): T = null as T -fun test11(): View4 = findViewById11() +fun test11(): View4 = findViewById11() object Obj { fun findViewById1(): T = null as T - fun test1(): View1 = findViewById1() + fun test1(): View1 = findViewById1() fun findViewById2(): T = null as T fun test2(): View2 = findViewById2() inline fun findViewById3(): T = null as T - fun test3(): View1 = findViewById3() + fun test3(): View1 = findViewById3() inline fun findViewById4(): T = null as T fun test4(): View2 = findViewById4() @@ -67,13 +67,13 @@ object Obj { fun test8(): View4 = findViewById8() fun findViewById9(): T where T: View3, T: View5 = null as T - fun test9(): View1 = findViewById9() + fun test9(): View1 = findViewById9() inline fun findViewById10(): T where T: View3, T: View5 = null as T - fun test10(): View1 = findViewById10() + fun test10(): View1 = findViewById10() fun findViewById11(): T = null as T - fun test11(): View4 = findViewById11() + fun test11(): View4 = findViewById11() } interface A diff --git a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/exactAnnotation.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/exactAnnotation.fir.kt index fdc90a8c182..bc0a223c68a 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/exactAnnotation.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve/exactAnnotation.fir.kt @@ -7,5 +7,5 @@ fun test1(l: List) { val i: Int = l.firstTyped() - val s: String = l.firstTyped() + val s: String = l.firstTyped() } diff --git a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt index 6123013605c..41d99388a33 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/types/model/TypeSystemContext.kt @@ -332,6 +332,8 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui private fun computeEffectiveVariance(parameter: TypeParameterMarker, argument: TypeArgumentMarker): TypeVariance? = AbstractTypeChecker.effectiveVariance(parameter.getVariance(), argument.getVariance()) + + val isK2: Boolean } diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt index a7edda92184..b1cbea8c5a7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/checker/ClassicTypeSystemContext.kt @@ -902,6 +902,9 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy return this is UnwrappedType && constructor is NewTypeVariableConstructor } + override val isK2: Boolean + get() = false + class WA // Workaround for KT-52313 }