[FIR] Fix inconsistent RETURN_TYPE_MISMATCH and TYPE_MISMATCH reporting on functions and properties

^KT-51203 Fixed
This commit is contained in:
Ivan Kochurkin
2022-03-17 16:34:19 +03:00
committed by teamcity
parent 4617615fd9
commit c6f52893fb
42 changed files with 82 additions and 77 deletions
@@ -15,4 +15,4 @@ public interface J2 {
}
// FILE: main.kt
fun baz(j2: J2): Any = <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>j2.bar().foo()<!> // Any..Any?
fun baz(j2: J2): Any = <!RETURN_TYPE_MISMATCH!>j2.bar().foo()<!> // Any..Any?
@@ -21,5 +21,5 @@ fun f(): String = "test"
class A {
fun schedule1(e: Executor): Future<String> = e.submit(::f)
fun schedule2(e: Executor): Future<String> = <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>e.submit { f() }<!>
fun schedule2(e: Executor): Future<String> = <!RETURN_TYPE_MISMATCH!>e.submit { f() }<!>
}
@@ -19,12 +19,12 @@ operator fun Impl2.unaryMinus() = Impl2()
// See also KT-10384: in non-error functions, as is necessary!
fun add1(x: Impl2, y: Base): Impl1 = x as Base + y
fun error1(x: Impl2, y: Base): Impl1 = <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>x + y<!>
fun error1(x: Impl2, y: Base): Impl1 = <!RETURN_TYPE_MISMATCH!>x + y<!>
fun add2(x: Base, y: Impl2): Impl1 = x + y as Base
fun error2(x: Base, y: Impl2): Impl1 = <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>x + y<!>
fun error2(x: Base, y: Impl2): Impl1 = <!RETURN_TYPE_MISMATCH!>x + y<!>
fun minus3(x: Impl2): Impl1 = -(x as Base)
fun error3(x: Impl2): Impl1 = <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>-x<!>
fun error3(x: Impl2): Impl1 = <!RETURN_TYPE_MISMATCH!>-x<!>
@@ -27,7 +27,7 @@ fun testResultOfAnonFun2() =
fun testReturnFromAnonFun() =
run(fun () {
return if (true) 42 else println()
return <!RETURN_TYPE_MISMATCH!>if (true) 42 else println()<!>
})
fun testReturn1() =
@@ -37,9 +37,9 @@ fun test4() = run {
val foo: Int
get() = run {
if (true) return ""
if (true) return <!RETURN_TYPE_MISMATCH!>""<!>
return
<!RETURN_TYPE_MISMATCH!>return<!>
}
fun test(): Int = run {
@@ -3,16 +3,16 @@
fun test1(): Int = <!RETURN_TYPE_MISMATCH!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
fun test2(): Int = <!RETURN_TYPE_MISMATCH!>{ 1 }<!>
val test3: () -> Int = fun (): Int = { <!RETURN_NOT_ALLOWED!>return<!> 1 }
val test4: () -> Int = fun (): Int = { 1 }
val test3: () -> Int = fun (): Int = <!RETURN_TYPE_MISMATCH!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
val test4: () -> Int = fun (): Int = <!RETURN_TYPE_MISMATCH!>{ 1 }<!>
fun test5(): Int { return <!RETURN_TYPE_MISMATCH!>{ 1 }<!> }
fun test6(): Int = <!RETURN_TYPE_MISMATCH!>fun (): Int = 1<!>
fun outer() {
fun test1(): Int = <!RETURN_TYPE_MISMATCH!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
fun test2(): Int = <!RETURN_TYPE_MISMATCH!>{ 1 }<!>
val test3: () -> Int = fun (): Int = { <!RETURN_NOT_ALLOWED!>return<!> 1 }
val test4: () -> Int = fun (): Int = { 1 }
val test3: () -> Int = fun (): Int = <!RETURN_TYPE_MISMATCH!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
val test4: () -> Int = fun (): Int = <!RETURN_TYPE_MISMATCH!>{ 1 }<!>
fun test5(): Int { return <!RETURN_TYPE_MISMATCH!>{ 1 }<!> }
fun test6(): Int = <!RETURN_TYPE_MISMATCH!>fun (): Int = 1<!>
}
@@ -20,16 +20,16 @@ fun outer() {
class Outer {
fun test1(): Int = <!RETURN_TYPE_MISMATCH!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
fun test2(): Int = <!RETURN_TYPE_MISMATCH!>{ 1 }<!>
val test3: () -> Int = fun (): Int = { <!RETURN_NOT_ALLOWED!>return<!> 1 }
val test4: () -> Int = fun (): Int = { 1 }
val test3: () -> Int = fun (): Int = <!RETURN_TYPE_MISMATCH!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
val test4: () -> Int = fun (): Int = <!RETURN_TYPE_MISMATCH!>{ 1 }<!>
fun test5(): Int { return <!RETURN_TYPE_MISMATCH!>{ 1 }<!> }
fun test6(): Int = <!RETURN_TYPE_MISMATCH!>fun (): Int = 1<!>
class Nested {
fun test1(): Int = <!RETURN_TYPE_MISMATCH!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
fun test2(): Int = <!RETURN_TYPE_MISMATCH!>{ 1 }<!>
val test3: () -> Int = fun (): Int = { <!RETURN_NOT_ALLOWED!>return<!> 1 }
val test4: () -> Int = fun (): Int = { 1 }
val test3: () -> Int = fun (): Int = <!RETURN_TYPE_MISMATCH!>{ <!RETURN_NOT_ALLOWED!>return<!> 1 }<!>
val test4: () -> Int = fun (): Int = <!RETURN_TYPE_MISMATCH!>{ 1 }<!>
fun test5(): Int { return <!RETURN_TYPE_MISMATCH!>{ 1 }<!> }
fun test6(): Int = <!RETURN_TYPE_MISMATCH!>fun (): Int = 1<!>
}
@@ -24,4 +24,4 @@ class C<R>() {
}
var c1: Int by C()
var c2: Int by <!DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>C<Number>()<!>
var c2: Int by <!DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH!>C<Number>()<!>
@@ -12,5 +12,5 @@ fun String.provideDelegate(a: Any?, p: KProperty<*>) = StringDelegate(this)
operator fun String.getValue(a: Any?, p: KProperty<*>) = this
val test1: String by "OK"
val test2: Int by <!DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>"OK"<!>
val test2: Int by <!DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH!>"OK"<!>
val test3 by "OK"
@@ -2,7 +2,7 @@
import kotlin.reflect.KProperty
val c: Int by <!DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>Delegate()<!>
val c: Int by <!DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH!>Delegate()<!>
class Delegate {
operator fun getValue(t: Any?, p: KProperty<*>): String {
@@ -2,8 +2,8 @@ val foo = fun(a: Int): String {
if (a == 1) return "4"
when (a) {
5 -> return "2"
3 -> return null
2 -> return 2
3 -> return <!NULL_FOR_NONNULL_TYPE!>null<!>
2 -> return <!RETURN_TYPE_MISMATCH!>2<!>
}
return ""
}
}
@@ -11,8 +11,8 @@ fun main() {
val a0: () -> Int = <!INITIALIZER_TYPE_MISMATCH!>fun(): String = "1"<!>
val a1: () -> Int = <!INITIALIZER_TYPE_MISMATCH!>(fun() = "1")<!>
val a2: () -> Unit = (fun() = "1")
val a3: Unit = <!INITIALIZER_TYPE_MISMATCH!>(fun() = "1")<!>
val a2: () -> Unit = (fun() = <!RETURN_TYPE_MISMATCH!>"1"<!>)
val a3: Unit = <!INITIALIZER_TYPE_MISMATCH!>(fun() = <!RETURN_TYPE_MISMATCH!>"1"<!>)<!>
val a4 = (fun() = "1")
val a5 = (fun(): String = "1")
val a6: () -> Int = (fun() = 1)
@@ -5,7 +5,7 @@ val a: () -> Int = <!INITIALIZER_TYPE_MISMATCH!>l@ {
}<!>
val b: () -> Unit = l@ {
if (flag) return@l 4
if (flag) return@l <!RETURN_TYPE_MISMATCH!>4<!>
}
val c: () -> Any = l@ {
@@ -1,6 +0,0 @@
val flag = true
val a = b@ {
if (flag) return@b 4
return@b
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
val flag = true
val a = b@ {
@@ -1,6 +1,6 @@
fun test(a: Int) {
run<Int>f@{
if (a > 0) return@f <!ARGUMENT_TYPE_MISMATCH!>""<!>
if (a > 0) return@f <!ARGUMENT_TYPE_MISMATCH, RETURN_TYPE_MISMATCH!>""<!>
return@f 1
}
@@ -20,7 +20,7 @@ fun test(a: A<out CharSequence>, z: Out<CharSequence>) {
a.bar { <!ARGUMENT_TYPE_MISMATCH, TYPE_MISMATCH!>z.id()<!> }
a.foo {
z.foobar(if (1 > 2) return@foo <!ARGUMENT_TYPE_MISMATCH!>""<!> else "")
z.foobar(if (1 > 2) return@foo <!ARGUMENT_TYPE_MISMATCH, RETURN_TYPE_MISMATCH!>""<!> else "")
<!ARGUMENT_TYPE_MISMATCH!>""<!>
}
}
@@ -12,7 +12,7 @@ fun foo(): String? {
run {
if (true) return@run
if (true) return <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>Obj()<!> // correct error, type check against return type of function "foo"
if (true) return <!RETURN_TYPE_MISMATCH!>Obj()<!> // correct error, type check against return type of function "foo"
}
run {
@@ -12,7 +12,7 @@ val a: () -> Unit = l@{
val b: () -> Unit = l@{
// Error, coercion can't be applied at this position!
if (true) return@l "hello"
if (true) return@l <!RETURN_TYPE_MISMATCH!>"hello"<!>
// However, this is OK, because here coercion is applied
"hello"
@@ -103,7 +103,7 @@ fun main() {
select(
id { x, y -> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Int")!>x<!>.inv() + <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Number")!>y<!>.toByte() },
id<(Int, Number) -> Int> { x, y -> x.inv() },
{} as (Number, Number) -> Int
<!RETURN_TYPE_MISMATCH!>{}<!> as (Number, Number) -> Int
)
// Inferring lambda parameter types by a few expected types (a few upper constraints)
@@ -7,4 +7,4 @@ class Foo<K>
fun main() {
val x = foo<Int, Foo<<!UNRESOLVED_REFERENCE!>_<!>>> { <!ARGUMENT_TYPE_MISMATCH!>it.toFloat()<!> }
}
}
@@ -1,7 +1,7 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE
// Related issue: KT-28654
fun <K> select(): K = <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>run { }<!>
fun <K> select(): K = <!RETURN_TYPE_MISMATCH!>run { }<!>
fun test() {
val x: Int = select()
@@ -14,4 +14,4 @@ fun doTheMapThing2(elements: List<CharSequence>): List<String> {
return elements.flatMap {
<!ARGUMENT_TYPE_MISMATCH!>if (it is String) listOf("Yeah") else null<!> // it's OK with `if`
}
}
}
@@ -11,14 +11,14 @@ abstract class Buggy {
}
val anotherThree : Int
get() = <!TYPE_MISMATCH!>coll.find{ it > 3 }<!> // does not work here
get() = <!RETURN_TYPE_MISMATCH!>coll.find{ it > 3 }<!> // does not work here
val yetAnotherThree : Int
get() = <!TYPE_MISMATCH!>coll.find({ v:Int -> v > 3 })<!> // neither here
get() = <!RETURN_TYPE_MISMATCH!>coll.find({ v:Int -> v > 3 })<!> // neither here
val extendedGetter : Int
get() {
return <!TYPE_MISMATCH!>coll.find{ it > 3 }<!> // not even here!
return <!RETURN_TYPE_MISMATCH!>coll.find{ it > 3 }<!> // not even here!
}
}
@@ -15,18 +15,18 @@ class SomeClass {
val e = E.VALUE
val withoutType: LambdaWithReceiver
get() = when (e) {
get() = <!RETURN_TYPE_MISMATCH!>when (e) {
E.VALUE -> { param ->
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>method<!>(param)
}
}
}<!>
val withExplicitType: LambdaWithReceiver
get() = when (e) {
get() = <!RETURN_TYPE_MISMATCH!>when (e) {
E.VALUE -> { param: Parameter ->
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>method<!>(param)
}
}
}<!>
}
class OtherClass {
@@ -38,8 +38,8 @@ class OtherClass {
val e2 = E.VALUE
val staticWithExplicitType: LambdaWithReceiver
get() = when (e2) {
get() = <!RETURN_TYPE_MISMATCH!>when (e2) {
E.VALUE -> { param: Parameter ->
<!UNRESOLVED_REFERENCE!>method<!>(param)
}
}
}<!>
@@ -8,7 +8,7 @@ fun <T> f(expression : T) : G<out T> = G<T>()
fun foo() : G<Point> {
val p = Point()
return <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>f<Point>(p)<!>
return <!RETURN_TYPE_MISMATCH!>f<Point>(p)<!>
}
class Out<out T>() {}
@@ -1,6 +1,6 @@
class A() {
var x: Int = 0
get() = "s"
get() = <!RETURN_TYPE_MISMATCH!>"s"<!>
set(value: <!WRONG_SETTER_PARAMETER_TYPE!>String<!>) {
field = <!ASSIGNMENT_TYPE_MISMATCH!>value<!>
}
@@ -8,7 +8,7 @@ class A() {
get(): <!WRONG_GETTER_RETURN_TYPE("kotlin/Int; kotlin/String")!>String<!> = "s"
val z: Int
get() {
return "s"
return <!RETURN_TYPE_MISMATCH!>"s"<!>
}
var a: Any = 1
@@ -27,7 +27,7 @@ class A() {
}
val e = 1
get(): <!WRONG_GETTER_RETURN_TYPE!>String<!> {
return field
return <!RETURN_TYPE_MISMATCH!>field<!>
}
}
@@ -16,7 +16,7 @@ fun <T> LiveData<T>.observe(a: Any, observer: (T) -> Unit): Observer<T> {
}
// FILE: test.kt
fun <T> test1(r: Runnable, l: LiveData<T>): Observer<T> = <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>l.observe(r) { }<!> // partial conversion
fun <T> test1(r: Runnable, l: LiveData<T>): Observer<T> = <!RETURN_TYPE_MISMATCH!>l.observe(r) { }<!> // partial conversion
fun <T> test2(r: Runnable, o: Observer<T>, l: LiveData<T>) {
val a = l.observe(r, o) // no conversion
@@ -6,10 +6,10 @@ class A {
constructor() {
if (1 == 1) {
return
return 1
return <!RETURN_TYPE_MISMATCH!>1<!>
}
return
return <!TYPE_MISMATCH!>foo()<!>
return <!RETURN_TYPE_MISMATCH!>foo()<!>
}
fun foo(): Int = 1
@@ -1,5 +1,5 @@
fun foo(): Int {
var i: Int? = 42
i = null
return <!RETURN_TYPE_MISMATCH, TYPE_MISMATCH!>i + 1<!>
return <!RETURN_TYPE_MISMATCH!>i + 1<!>
}