NI: do type checking for anonymous functions not inside a call

^KT-38890 Fixed
^KT-38439 Fixed
This commit is contained in:
Victor Petukhov
2020-05-19 11:31:15 +03:00
parent 425ce8c3ab
commit eff5f3a242
18 changed files with 174 additions and 25 deletions
@@ -9,7 +9,7 @@ fun testReturnType(foo: String) {
val bas: () -> String = fun () = foo
val bag: () -> Int = <!OI;TYPE_MISMATCH!>fun () = foo<!>
val bag: () -> Int = <!TYPE_MISMATCH!>fun () = foo<!>
}
fun testParamType() {
@@ -18,7 +18,7 @@ fun testParamType() {
bar.checkType { _<(String) -> Unit>() }
val bas: (String) -> Unit = fun (param: String) {}
val bag: (Int) -> Unit = <!OI;TYPE_MISMATCH!>fun (<!EXPECTED_PARAMETER_TYPE_MISMATCH!>param: String<!>) {}<!>
val bag: (Int) -> Unit = <!TYPE_MISMATCH!>fun (<!EXPECTED_PARAMETER_TYPE_MISMATCH!>param: String<!>) {}<!>
}
fun testReceiverType() {
@@ -28,5 +28,5 @@ fun testReceiverType() {
val bas: String.() -> Unit = fun String.() {}
val bag: Int.() -> Unit = <!OI;TYPE_MISMATCH!>fun String.() {}<!>
val bag: Int.() -> Unit = <!TYPE_MISMATCH!>fun String.() {}<!>
}
@@ -17,4 +17,4 @@ fun test2(a: () -> List<Int>) {
val a: (Int) -> Unit = fun(x) { checkSubtype<Int>(x) }
val b: (Int) -> Unit = <!OI;TYPE_MISMATCH!>fun(<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>) {}<!>
val b: (Int) -> Unit = <!TYPE_MISMATCH!>fun(<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>) {}<!>
@@ -6,22 +6,22 @@ val a = fun (<!CANNOT_INFER_PARAMETER_TYPE!>x<!>) = <!DEBUG_INFO_ELEMENT_WITH_ER
val b: (Int) -> Int = fun (x) = x + 3
val c: (Int, String) -> Int = <!OI;TYPE_MISMATCH!>fun <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>(x)<!> = 3<!>
val c: (Int, String) -> Int = <!TYPE_MISMATCH!>fun <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>(x)<!> = 3<!>
val d: (Int, String) -> Int = <!OI;TYPE_MISMATCH!>fun <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>(x)<!> = 3<!>
val d: (Int, String) -> Int = <!TYPE_MISMATCH!>fun <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>(x)<!> = 3<!>
val e: (Int, String) -> Int = <!OI;TYPE_MISMATCH!>fun <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>(<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>)<!> = 3<!>
val e: (Int, String) -> Int = <!TYPE_MISMATCH!>fun <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>(<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>)<!> = 3<!>
val f: (Int) -> Int = <!OI;TYPE_MISMATCH!>fun (<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>) = 3<!>
val f: (Int) -> Int = <!TYPE_MISMATCH!>fun (<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>) = 3<!>
fun test1(a: (Int) -> Unit) {
test1(fun (x) { checkSubtype<Int>(x)})
}
fun test2(a: (Int) -> Unit) {
test2(<!TYPE_MISMATCH!>fun (<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>) {}<!>)
test2(<!NI;TYPE_MISMATCH, TYPE_MISMATCH!>fun (<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>) {}<!>)
}
fun test3(a: (Int, String) -> Unit) {
test3(<!TYPE_MISMATCH!>fun <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>(<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>)<!> {}<!>)
test3(<!NI;TYPE_MISMATCH, TYPE_MISMATCH!>fun <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>(<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>)<!> {}<!>)
}
@@ -1,3 +1,3 @@
// !WITH_NEW_INFERENCE
fun foo(<!UNUSED_PARAMETER!>f<!>: String.() -> Int) {}
val test = foo(<!NI;TYPE_MISMATCH, TYPE_MISMATCH!>fun <!NI;EXPECTED_PARAMETERS_NUMBER_MISMATCH!>()<!> = <!UNRESOLVED_REFERENCE!>length<!><!>)
val test = foo(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, TYPE_MISMATCH!>fun <!NI;EXPECTED_PARAMETERS_NUMBER_MISMATCH!>()<!> = <!UNRESOLVED_REFERENCE!>length<!><!>)
@@ -16,6 +16,6 @@ fun test(s: Sub) {
t: Trait -> s
}
foo(<!TYPE_MISMATCH!>fun(<!EXPECTED_PARAMETER_TYPE_MISMATCH!>t: Sub<!>) = s<!>)
foo(<!NI;TYPE_MISMATCH, TYPE_MISMATCH!>fun(<!EXPECTED_PARAMETER_TYPE_MISMATCH!>t: Sub<!>) = s<!>)
foo(<!TYPE_MISMATCH!>fun(t): Super = s<!>)
}
@@ -0,0 +1,40 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -UNCHECKED_CAST
// Issues: KT-38890, KT-38439
fun foo(x: () -> Int) {}
fun <T>id(x: T) = x
// Before the fix, there wasn't any type mismatch error in NI due to result type not being a subtype of expected type
fun main() {
val x: () -> Int = { "" }
val a0: () -> Int = fun(): String = "1"
val a1: () -> Int = (fun() = "1")
val a2: () -> Unit = (fun() = "1")
val a3: Unit = (fun() = "1")
val a4 = (fun() = "1")
val a5 = (fun(): String = "1")
val a6: () -> Int = (fun() = 1)
val a7: () -> Int = (fun(): String = "1") as () -> Int
val a8: () -> Int = fun(): String = "1"
val a9: () -> () -> () -> Int = fun(): () -> () -> String = fun(): () -> String = fun(): String = "1"
<!INAPPLICABLE_CANDIDATE!>foo<!>(fun(): String = "1")
<!INAPPLICABLE_CANDIDATE!>foo<!>(((fun(): String = "1")))
val a10: Int.(String) -> Int = fun (x: String) = 10
val a11: () -> () -> () -> Int = fun() = fun() = fun(): String = "1"
val a12: Int = fun(): String = "1"
val a13: Int = fun() = fun(): String = "1"
val a14: Int = fun() = fun() = "1"
val a15: Int = fun() = fun() = {}
val a16: Int = fun() = fun() {}
val a17: () -> Unit = fun() {}
val a18: () -> Int = fun() {}
val a19: () -> () -> Int = fun() = fun() {}
val a20: () -> () -> () -> Unit = fun() = fun() = {}
val a21: () -> () -> () -> Int = fun() = fun() = {}
}
@@ -0,0 +1,40 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -UNCHECKED_CAST
// Issues: KT-38890, KT-38439
fun foo(x: () -> Int) {}
fun <T>id(x: T) = x
// Before the fix, there wasn't any type mismatch error in NI due to result type not being a subtype of expected type
fun main() {
val x: () -> Int = { <!TYPE_MISMATCH!>""<!> }
val a0: () -> Int = <!TYPE_MISMATCH!>fun(): String = "1"<!>
val a1: () -> Int = (<!TYPE_MISMATCH!>fun() = "1"<!>)
val a2: () -> Unit = (<!TYPE_MISMATCH!>fun() = "1"<!>)
val a3: Unit = (<!TYPE_MISMATCH!>fun() = "1"<!>)
val a4 = (fun() = "1")
val a5 = (fun(): String = "1")
val a6: () -> Int = (fun() = 1)
val a7: () -> Int = (fun(): String = "1") as () -> Int
val a8: () -> Int = <!TYPE_MISMATCH!>fun(): String = "1"<!>
val a9: () -> () -> () -> Int = <!TYPE_MISMATCH!>fun(): () -> () -> String = fun(): () -> String = fun(): String = "1"<!>
foo(<!TYPE_MISMATCH!>fun(): String = "1"<!>)
foo(((<!TYPE_MISMATCH!>fun(): String = "1"<!>)))
val a10: Int.(String) -> Int = <!TYPE_MISMATCH!>fun (x: String) = 10<!>
val a11: () -> () -> () -> Int = <!TYPE_MISMATCH!>fun() = fun() = fun(): String = "1"<!>
val a12: Int = <!TYPE_MISMATCH!>fun(): String = "1"<!>
val a13: Int = <!TYPE_MISMATCH!>fun() = fun(): String = "1"<!>
val a14: Int = <!TYPE_MISMATCH!>fun() = fun() = "1"<!>
val a15: Int = <!TYPE_MISMATCH!>fun() = fun() = {}<!>
val a16: Int = <!TYPE_MISMATCH!>fun() = fun() {}<!>
val a17: () -> Unit = fun() {}
val a18: () -> Int = <!TYPE_MISMATCH!>fun() {}<!>
val a19: () -> () -> Int = <!TYPE_MISMATCH!>fun() = fun() {}<!>
val a20: () -> () -> () -> Unit = fun() = fun() = {}
val a21: () -> () -> () -> Int = <!TYPE_MISMATCH!>fun() = fun() = {}<!>
}
@@ -0,0 +1,5 @@
package
public fun foo(/*0*/ x: () -> kotlin.Int): kotlin.Unit
public fun </*0*/ T> id(/*0*/ x: T): T
public fun main(): kotlin.Unit
@@ -0,0 +1,24 @@
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun take(fn: () -> List<String>) {}
fun <L> inferFromLambda(fn: () -> L): L = TODO()
fun <L> inferFromLambda2(fn: (Int) -> 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()))
id<String>(inferFromLambda2(fun() = materialize()))
}
@@ -1,9 +1,9 @@
// FIR_IDENTICAL
// !LANGUAGE: +NewInference
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun take(fn: () -> List<String>) {}
fun <L> inferFromLambda(fn: () -> L): L = TODO()
fun <L> inferFromLambda2(fn: (Int) -> L): L = TODO()
fun <T> materialize(): T = TODO()
fun <I> id(arg: I) = arg
@@ -20,4 +20,5 @@ fun testFunctions() {
fun testNestedCalls() {
id<String>(inferFromLambda { materialize() })
id<String>(inferFromLambda(fun() = materialize()))
id<String>(inferFromLambda2(<!TYPE_MISMATCH, TYPE_MISMATCH, TYPE_MISMATCH!>fun<!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>()<!> = materialize()<!>))
}
@@ -2,6 +2,7 @@ package
public fun </*0*/ I> id(/*0*/ arg: I): I
public fun </*0*/ L> inferFromLambda(/*0*/ fn: () -> L): L
public fun </*0*/ L> inferFromLambda2(/*0*/ fn: (kotlin.Int) -> 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
@@ -153,7 +153,7 @@ fun main() {
// Convert to extension lambda is impossible because the lambda parameter types aren't specified explicitly
select(id(fun String.(x: String) {}), id(fun(x: String, y: String) { }), <!TYPE_MISMATCH!>{ <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>x, <!CANNOT_INFER_PARAMETER_TYPE!>y<!><!> -> x }<!>)
select(id(id(fun(x: String, y: String) { }), <!TOO_MANY_ARGUMENTS!>fun String.(x: String) {}<!>), { x, y -> x })
val x26: Int.(String) -> Int = fun (x: String) = 10 // it must be error, see KT-38439
val x26: Int.(String) -> Int = <!TYPE_MISMATCH!>fun (x: String) = 10<!> // it must be error, see KT-38439
// Receiver must be specified in anonymous function declaration
val x27: Int.(String) -> Int = id(<!TYPE_MISMATCH!>fun <!EXPECTED_PARAMETERS_NUMBER_MISMATCH!>(<!EXPECTED_PARAMETER_TYPE_MISMATCH!>x: String<!>)<!> = 10<!>)
select(id<Int.(String) -> Unit> {}, { x: Int, y: String -> x })
+1 -1
View File
@@ -15,7 +15,7 @@ class A() {
//more tests
val g : () -> Unit = { <!UNUSED_EXPRESSION!>42<!> }
val gFunction : () -> Unit = <!OI;TYPE_MISMATCH!>fun(): Int = 1<!>
val gFunction : () -> Unit = <!TYPE_MISMATCH!>fun(): Int = 1<!>
val h : () -> Unit = { doSmth() }