FIR: Support adding expect type to calls in foo() as R position

See https://kotlinlang.org/docs/whatsnew12.html#support-for-foo-as-a-shorthand-for-this-foo
This commit is contained in:
Denis.Zharkov
2021-05-26 17:44:05 +03:00
committed by TeamCityServer
parent 6136526a3a
commit d932d5b0a5
20 changed files with 219 additions and 49 deletions
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// TARGET_BACKEND: JVM
// WITH_RUNTIME
@@ -8,6 +8,6 @@ object CommonCase {
operator fun <D, E, R> Fas<D, E, R>.provideDelegate(host: D, p: Any?): Fas<D, E, R> = TODO()
operator fun <D, E, R> Fas<D, E, R>.getValue(receiver: E, p: Any?): R = TODO()
val Long.test1: String by <!TYPE_MISMATCH!>delegate()<!> // common test, not working because of Inference1
val Long.test1: String by <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>delegate<!>() // common test, not working because of Inference1
val Long.test2: String by delegate<CommonCase, Long, String>() // should work
}
@@ -13,6 +13,6 @@ val asA = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>().<!UNRESOLVED_RE
val receiverParenthesized = (<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>()).<!UNRESOLVED_REFERENCE!>fooA<!>() as A
val no2A = A().<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>fooA<!>().<!UNRESOLVED_REFERENCE!>fooA<!>() as A
val correct1 = A().<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>fooA<!>() as A
val correct2 = foo<A>().<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>fooA<!>() as A
val correct3 = A().fooA<A>().<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>fooA<!>() as A
val correct1 = A().fooA() as A
val correct2 = foo<A>().fooA() as A
val correct3 = A().fooA<A>().fooA() as A
@@ -4,17 +4,17 @@ fun <T> foo(): T = TODO()
fun <V> id(value: V) = value
val asString = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() as String
val asString = foo() as String
val viaId = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>id<!>(foo()) as String
val insideId = id(<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() as String)
val insideId = id(foo() as String)
val asList = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() as List<String>
val asList = foo() as List<String>
val asStarList = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() as List<*>
val asStarList = foo() as List<*>
val safeAs = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() as? String
val safeAs = foo() as? String
val fromIs = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() is String
val fromNoIs = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() !is String
@@ -11,6 +11,6 @@ class A {
}
}
val x = A().<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() as String
val y = A.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo2<!>() as String
val z = pp.A.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo2<!>() as String
val x = A().foo() as String
val y = A.foo2() as String
val z = pp.A.foo2() as String
@@ -8,15 +8,15 @@ fun <T> foo(): T = TODO()
fun <V> id(value: V) = value
val par1 = (<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>()) as String
val par2 = ((<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>())) as String
val par1 = (foo()) as String
val par2 = ((foo())) as String
val par3 = (dd@ (<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>())) as String
val par3 = (dd@ (foo())) as String
val par4 = ( @bar() (<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>())) as String
val par4 = ( @bar() (foo())) as String
object X {
fun <T> foo(): T = TODO()
}
val par5 = ( @bar() X.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>()) as String
val par5 = ( @bar() X.foo()) as String
@@ -5,13 +5,13 @@ class X<S> {
}
fun test(x: X<Number>) {
val y = x.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() as Int
val y = x.foo() as Int
}
fun <S, D: S> g() {
fun <T : S> foo(): T = TODO()
val y = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() as Int
val y = <!NEW_INFERENCE_ERROR!>foo()<!> as Int
val y2 = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() as D
val y2 = foo() as D
}
@@ -0,0 +1,11 @@
// FIR_IDENTICAL
// SKIP_TXT
// !LANGUAGE: +ExpectedTypeFromCast
class X {
fun <T> foo(): T = TODO()
}
fun test(x: X?) {
val y = x?.foo() as Int
}
@@ -0,0 +1,58 @@
// !LANGUAGE: +ExpectedTypeFromCast
// !DIAGNOSTICS: -UNUSED_VARIABLE -DEBUG_INFO_LEAKING_THIS
// FILE: a/View.java
package a;
public class View {
}
// FILE: a/Test.java
package a;
public class Test {
public <T extends View> T findViewById(int id);
}
// FILE: 1.kt
package a
class X : View()
class Y<T> : View()
val xExplicit: X = Test().findViewById(0)
val xCast = Test().findViewById(0) as X
val xCastExplicitType = Test().findViewById<X>(0) as X
val xSafeCastExplicitType = Test().findViewById<X>(0) as? X
val yExplicit: Y<String> = Test().findViewById(0)
val yCast = Test().findViewById(0) as Y<String>
class TestChild : Test() {
val xExplicit: X = findViewById(0)
val xCast = findViewById(0) as X
val yExplicit: Y<String> = findViewById(0)
val yCast = findViewById(0) as Y<String>
}
fun test(t: Test) {
val xExplicit: X = t.findViewById(0)
val xCast = t.findViewById(0) as X
val yExplicit: Y<String> = t.findViewById(0)
val yCast = t.findViewById(0) as Y<String>
}
fun test2(t: Test?) {
val xSafeCallSafeCast = t?.findViewById(0) <!USELESS_CAST!>as? X<!>
val xSafeCallSafeCastExplicitType = t?.findViewById<X>(0) <!USELESS_CAST!>as? X<!>
val xSafeCallCast = t?.findViewById(0) as X
val xSafeCallCastExplicitType = t<!UNNECESSARY_SAFE_CALL!>?.<!>findViewById<X>(0) as X
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// !LANGUAGE: +ExpectedTypeFromCast
// !DIAGNOSTICS: -UNUSED_VARIABLE -DEBUG_INFO_LEAKING_THIS
@@ -25,35 +24,35 @@ class X : View()
class Y<T> : View()
val xExplicit: X = Test().findViewById(0)
val xCast = Test().<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>findViewById<!>(0) as X
val xCast = Test().findViewById(0) as X
val xCastExplicitType = Test().findViewById<X>(0) as X
val xSafeCastExplicitType = Test().findViewById<X>(0) <!USELESS_CAST!>as? X<!>
val yExplicit: Y<String> = Test().findViewById(0)
val yCast = Test().<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>findViewById<!>(0) as Y<String>
val yCast = Test().findViewById(0) as Y<String>
class TestChild : Test() {
val xExplicit: X = findViewById(0)
val xCast = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>findViewById<!>(0) as X
val xCast = findViewById(0) as X
val yExplicit: Y<String> = findViewById(0)
val yCast = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>findViewById<!>(0) as Y<String>
val yCast = findViewById(0) as Y<String>
}
fun test(t: Test) {
val xExplicit: X = t.findViewById(0)
val xCast = t.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>findViewById<!>(0) as X
val xCast = t.findViewById(0) as X
val yExplicit: Y<String> = t.findViewById(0)
val yCast = t.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>findViewById<!>(0) as Y<String>
val yCast = t.findViewById(0) as Y<String>
}
fun test2(t: Test?) {
val xSafeCallSafeCast = t?.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>findViewById<!>(0) as? X
val xSafeCallSafeCast = t?.findViewById(0) as? X
val xSafeCallSafeCastExplicitType = t?.findViewById<X>(0) <!USELESS_CAST!>as? X<!>
val xSafeCallCast = t?.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>findViewById<!>(0) as X
val xSafeCallCast = t?.findViewById(0) as X
val xSafeCallCastExplicitType = t<!UNNECESSARY_SAFE_CALL!>?.<!>findViewById<X>(0) as X
}
+2 -2
View File
@@ -8,9 +8,9 @@ inline fun <reified T> foo(): T {
}
fun test() {
val fooCall = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() as String // T in foo should be inferred to String
val fooCall = foo() as String // T in foo should be inferred to String
fooCall checkType { _<String>() }
val safeFooCall = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>() as? String
val safeFooCall = foo() as? String
safeFooCall checkType { _<String?>() }
}