K2: report empty intersection warnings from completion properly
This commit is contained in:
committed by
Space Team
parent
47fab61716
commit
a3f0e429e3
+6
@@ -18325,6 +18325,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
|||||||
runTest("compiler/testData/codegen/box/fir/differentSinceKotlin.kt");
|
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
|
@Test
|
||||||
@TestMetadata("ExtensionAlias.kt")
|
@TestMetadata("ExtensionAlias.kt")
|
||||||
public void testExtensionAlias() throws Exception {
|
public void testExtensionAlias() throws Exception {
|
||||||
|
|||||||
+6
@@ -18325,6 +18325,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
|||||||
runTest("compiler/testData/codegen/box/fir/differentSinceKotlin.kt");
|
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
|
@Test
|
||||||
@TestMetadata("ExtensionAlias.kt")
|
@TestMetadata("ExtensionAlias.kt")
|
||||||
public void testExtensionAlias() throws Exception {
|
public void testExtensionAlias() throws Exception {
|
||||||
|
|||||||
+2
-1
@@ -802,8 +802,9 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
return varargArgumentsExpression
|
return varargArgumentsExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: report warning with a checker and return true here only in case of errors
|
||||||
private fun FirNamedReferenceWithCandidate.hasAdditionalResolutionErrors(): Boolean =
|
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 {
|
private fun FirNamedReferenceWithCandidate.toResolvedReference(): FirNamedReference {
|
||||||
val errorDiagnostic = when {
|
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"
|
||||||
|
}
|
||||||
-41
@@ -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
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
interface I
|
interface I
|
||||||
open class C
|
open class C
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ fun <T: A> emptyNullableListOfA(): List<T>? = null
|
|||||||
|
|
||||||
fun testExclExcl() {
|
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
|
<!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)
|
doList(strangeNullableList { doInt(it) }!!) //lambda should be analyzed (at completion phase)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -14,4 +14,4 @@ fun main() {
|
|||||||
|
|
||||||
|
|
||||||
fun <T : Appendable> wtf(): T = TODO()
|
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 {
|
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>
|
fun <T : CharSequence> delegate() = null <!CAST_NEVER_SUCCEEDS!>as<!> ReadOnlyProperty<Problem, T>
|
||||||
}
|
}
|
||||||
|
|||||||
-84
@@ -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
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -FINAL_UPPER_BOUND -CAST_NEVER_SUCCEEDS
|
// !DIAGNOSTICS: -FINAL_UPPER_BOUND -CAST_NEVER_SUCCEEDS
|
||||||
// !LANGUAGE: +AllowEmptyIntersectionsInResultTypeResolver
|
// !LANGUAGE: +AllowEmptyIntersectionsInResultTypeResolver
|
||||||
|
|
||||||
|
|||||||
+6
@@ -18325,6 +18325,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/fir/differentSinceKotlin.kt");
|
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
|
@Test
|
||||||
@TestMetadata("ExtensionAlias.kt")
|
@TestMetadata("ExtensionAlias.kt")
|
||||||
public void testExtensionAlias() throws Exception {
|
public void testExtensionAlias() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user