K2: report empty intersection warnings from completion properly

This commit is contained in:
Mikhail Glukhikh
2023-03-02 10:25:21 +01:00
committed by Space Team
parent 47fab61716
commit a3f0e429e3
12 changed files with 38 additions and 129 deletions
@@ -18325,6 +18325,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/fir/differentSinceKotlin.kt");
}
@Test
@TestMetadata("emptyIntersectionWarning.kt")
public void testEmptyIntersectionWarning() throws Exception {
runTest("compiler/testData/codegen/box/fir/emptyIntersectionWarning.kt");
}
@Test
@TestMetadata("ExtensionAlias.kt")
public void testExtensionAlias() throws Exception {
@@ -18325,6 +18325,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/fir/differentSinceKotlin.kt");
}
@Test
@TestMetadata("emptyIntersectionWarning.kt")
public void testEmptyIntersectionWarning() throws Exception {
runTest("compiler/testData/codegen/box/fir/emptyIntersectionWarning.kt");
}
@Test
@TestMetadata("ExtensionAlias.kt")
public void testExtensionAlias() throws Exception {
@@ -802,8 +802,9 @@ class FirCallCompletionResultsWriterTransformer(
return varargArgumentsExpression
}
// TODO: report warning with a checker and return true here only in case of errors
private fun FirNamedReferenceWithCandidate.hasAdditionalResolutionErrors(): Boolean =
candidate.system.errors.any { it is InferredEmptyIntersection && it.kind.isDefinitelyEmpty }
candidate.system.errors.any { it is InferredEmptyIntersection }
private fun FirNamedReferenceWithCandidate.toResolvedReference(): FirNamedReference {
val errorDiagnostic = when {
@@ -0,0 +1,13 @@
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND_K1: JVM_IR
interface I
class View1
fun <T : View1> findViewById1(): T? = null
fun test1(): I? = findViewById1()
fun box(): String {
test1()
return "OK"
}
@@ -1,41 +0,0 @@
interface I
open class C
fun completed(): String = "..."
fun <T> incomplete(): T = null!!
fun <T : I> incompatibleI(): T = null!!
fun <T : C> incompatibleC(): T = null!!
val p = false
fun expectUnit(x: Unit) = x
fun test1() = run {
if (p) return@run
completed() // ok, not returned
}
fun test2() = run {
if (p) return@run
incomplete() // ? either uninferred T or Unit
}
fun test3() = run {
if (p) return@run
incompatibleI() // ? either uninferred T or error (Unit </: I)
}
fun test4() = <!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>run<!> {
if (p) return@run
incompatibleC() // ? either uninferred T or error (Unit </: C)
}
fun main() {
// all ok
expectUnit(test1())
expectUnit(test2())
expectUnit(test3())
expectUnit(test4())
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
interface I
open class C
@@ -13,7 +13,7 @@ fun <T: A> emptyNullableListOfA(): List<T>? = null
fun testExclExcl() {
<!INFERRED_TYPE_VARIABLE_INTO_POSSIBLE_EMPTY_INTERSECTION("T; a/A, kotlin/Int; final class and interface")!>doList<!>(emptyNullableListOfA()!!) //should be an error here
val l: List<Int> = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.collections.List<a.A & kotlin.Int>")!>id(emptyNullableListOfA()!!)<!>
val l: List<Int> = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.collections.List<a.A & kotlin.Int>")!><!INFERRED_TYPE_VARIABLE_INTO_POSSIBLE_EMPTY_INTERSECTION!>id<!>(emptyNullableListOfA()!!)<!>
doList(strangeNullableList { doInt(it) }!!) //lambda should be analyzed (at completion phase)
}
@@ -14,4 +14,4 @@ fun main() {
fun <T : Appendable> wtf(): T = TODO()
val bar: Int = wtf() // happily compiles
val bar: Int = <!INFERRED_TYPE_VARIABLE_INTO_POSSIBLE_EMPTY_INTERSECTION!>wtf<!>() // happily compiles
@@ -7,6 +7,6 @@ fun interface ReadOnlyProperty<in T, out V> {
}
class Problem {
val variable: Int by delegate() // delegate returns `ReadOnlyProperty<Problem, {CharSequence & Int}>`
val variable: Int by <!DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, INFERRED_TYPE_VARIABLE_INTO_POSSIBLE_EMPTY_INTERSECTION!>delegate()<!> // delegate returns `ReadOnlyProperty<Problem, {CharSequence & Int}>`
fun <T : CharSequence> delegate() = null <!CAST_NEVER_SUCCEEDS!>as<!> ReadOnlyProperty<Problem, T>
}
@@ -1,84 +0,0 @@
// !DIAGNOSTICS: -FINAL_UPPER_BOUND -CAST_NEVER_SUCCEEDS
// !LANGUAGE: +AllowEmptyIntersectionsInResultTypeResolver
interface I
class View1
open class View2
interface View3
abstract class View4
interface View5
fun <T: View1> findViewById1(): T = null as T
fun test1(): I = findViewById1()
fun <T: View2> findViewById2(): T = null as T
fun test2(): I = findViewById2()
inline fun <reified T: View1> findViewById3(): T = null as T
fun test3(): I = findViewById3()
inline fun <reified T: View2> findViewById4(): T = null as T
fun test4(): I = findViewById4()
fun <T: View3> findViewById5(): T = null as T
fun test5(): I = findViewById5()
inline fun <reified T: View3> findViewById6(): T = null as T
fun test6(): I = findViewById6()
fun <T: View4> findViewById7(): T = null as T
fun test7(): I = findViewById7()
inline fun <reified T: View4> findViewById8(): T = null as T
fun test8(): I = findViewById8()
fun <T> findViewById9(): T where T: View3, T: View5 = null as T
fun test9(): I = findViewById9()
inline fun <reified T> findViewById10(): T where T: View3, T: View5 = null as T
fun test10(): I = findViewById10()
fun <T: View2> findViewById11(): T = null as T
fun test11(): View4 = <!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>findViewById11<!>()
object Obj {
fun <T: I> findViewById1(): T = null as T
fun test1(): View1 = findViewById1()
fun <T: I> findViewById2(): T = null as T
fun test2(): View2 = findViewById2()
inline fun <reified T: I> findViewById3(): T = null as T
fun test3(): View1 = findViewById3()
inline fun <reified T: I> findViewById4(): T = null as T
fun test4(): View2 = findViewById4()
fun <T: I> findViewById5(): T = null as T
fun test5(): View3 = findViewById5()
inline fun <reified T: I> findViewById6(): T = null as T
fun test6(): View3 = findViewById6()
fun <T: I> findViewById7(): T = null as T
fun test7(): View4 = findViewById7()
inline fun <reified T: I> findViewById8(): T = null as T
fun test8(): View4 = findViewById8()
fun <T> findViewById9(): T where T: View3, T: View5 = null as T
fun test9(): View1 = findViewById9()
inline fun <reified T> findViewById10(): T where T: View3, T: View5 = null as T
fun test10(): View1 = findViewById10()
fun <T: View2> findViewById11(): T = null as T
fun test11(): View4 = <!INFERRED_TYPE_VARIABLE_INTO_EMPTY_INTERSECTION_WARNING!>findViewById11<!>()
}
interface A
open class B {
fun <T> f(): T where T : A, T : B = null as T
fun g(): A = f()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -FINAL_UPPER_BOUND -CAST_NEVER_SUCCEEDS
// !LANGUAGE: +AllowEmptyIntersectionsInResultTypeResolver
@@ -18325,6 +18325,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/fir/differentSinceKotlin.kt");
}
@Test
@TestMetadata("emptyIntersectionWarning.kt")
public void testEmptyIntersectionWarning() throws Exception {
runTest("compiler/testData/codegen/box/fir/emptyIntersectionWarning.kt");
}
@Test
@TestMetadata("ExtensionAlias.kt")
public void testExtensionAlias() throws Exception {