[NI] Make behaviour of anonymous functions consistent with lambdas

Fix completion of anonymous functions with expression body without expected type.
Premature completion led to losing type info from outer calls.
Also report type mismatches on empty lambda expressions.

KT-34729 In progress
This commit is contained in:
Pavel Kirpichenkov
2020-01-20 13:47:43 +03:00
parent 4554f91aff
commit 3a98c84105
14 changed files with 185 additions and 13 deletions
@@ -12,7 +12,7 @@ fun test(a: (Int) -> Int) {
}
fun test2(a: () -> List<Int>) {
test2(fun () = <!NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>listOf<!>())
test2(fun () = <!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>listOf<!>())
}
val a: (Int) -> Unit = fun(x) { checkSubtype<Int>(x) }
@@ -0,0 +1,19 @@
// !WITH_NEW_INFERENCE
// !DIAGNOSTICS: -UNUSED_PARAMETER
// !LANGUAGE: +NewInference
interface ILength {
val length: Int
}
class Impl(override val length: Int) : ILength
fun <T> foo(a: (Int) -> T) = 0
fun <T : ILength> bar(a: (Int) -> T) {
a(42).length
}
fun test() {
foo<String> { }
bar<Impl> { }
}
+19
View File
@@ -0,0 +1,19 @@
// !WITH_NEW_INFERENCE
// !DIAGNOSTICS: -UNUSED_PARAMETER
// !LANGUAGE: +NewInference
interface ILength {
val length: Int
}
class Impl(override val length: Int) : ILength
fun <T> foo(a: (Int) -> T) = 0
fun <T : ILength> bar(a: (Int) -> T) {
a(42).length
}
fun test() {
foo<String> <!NI;TYPE_MISMATCH!>{ <!OI;TYPE_MISMATCH!><!>}<!>
bar<Impl> <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>{ <!OI;TYPE_MISMATCH!><!>}<!>
}
@@ -0,0 +1,20 @@
package
public fun </*0*/ T : ILength> bar(/*0*/ a: (kotlin.Int) -> T): kotlin.Unit
public fun </*0*/ T> foo(/*0*/ a: (kotlin.Int) -> T): kotlin.Int
public fun test(): kotlin.Unit
public interface ILength {
public abstract val length: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class Impl : ILength {
public constructor Impl(/*0*/ length: kotlin.Int)
public open override /*1*/ val length: kotlin.Int
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,22 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun take(fn: () -> List<String>) {}
fun <L> inferFromLambda(fn: () -> L): L = TODO()
fun <T> materialize(): T = TODO()
fun <I> id(arg: I) = arg
fun testFunctions() {
take { materialize() }
take(fun() = materialize())
take(fun(): List<String> = materialize())
take(fun(): List<String> {
return materialize()
})
}
fun testNestedCalls() {
id<String>(inferFromLambda { materialize() })
id<String>(inferFromLambda(fun() = materialize()))
}
@@ -0,0 +1,22 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun take(fn: () -> List<String>) {}
fun <L> inferFromLambda(fn: () -> L): L = TODO()
fun <T> materialize(): T = TODO()
fun <I> id(arg: I) = arg
fun testFunctions() {
take { materialize() }
take(fun() = materialize())
take(fun(): List<String> = materialize())
take(fun(): List<String> {
return materialize()
})
}
fun testNestedCalls() {
id<String>(inferFromLambda { materialize() })
id<String>(inferFromLambda(fun() = materialize()))
}
@@ -0,0 +1,8 @@
package
public fun </*0*/ I> id(/*0*/ arg: I): I
public fun </*0*/ L> inferFromLambda(/*0*/ fn: () -> L): L
public fun </*0*/ T> materialize(): T
public fun take(/*0*/ fn: () -> kotlin.collections.List<kotlin.String>): kotlin.Unit
public fun testFunctions(): kotlin.Unit
public fun testNestedCalls(): kotlin.Unit