Support overload ambiguity resolution for callable references by expected type.
Resolve callable references taking into account expected callable types. This affects call resolution procedure (resolve 'foo' in for 'foo(::bar)') similar to the approach used for function literals: * During "shape arguments" phase of call resolution, callable references are resolved in independent context without expected type. If the callable reference is ambiguous, its shape type is a function placeholder type without parameter types and return type information. Otherwise, it is a reflection type for the resolved function or property. Upper-level call is resolved without taking into account ambiguous callable references. * During "complete call" phase of call resolution, resolve callable reference arguments to actual descriptors (if possible), and update constraint system for the given call accordingly. #KT-6982 Fixed #KT-5780 Fixed
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun foo() {}
|
||||
fun foo(s: String) {}
|
||||
|
||||
fun fn(f: () -> Unit) {}
|
||||
|
||||
fun test() {
|
||||
fn(::foo)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package
|
||||
|
||||
internal fun fn(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
|
||||
internal fun foo(): kotlin.Unit
|
||||
internal fun foo(/*0*/ s: kotlin.String): kotlin.Unit
|
||||
internal fun test(): kotlin.Unit
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun <T> ofType(x: T): T = x
|
||||
|
||||
fun foo() {}
|
||||
fun foo(s: String) {}
|
||||
|
||||
val x1 = ofType<() -> Unit>(::foo)
|
||||
val x2 = ofType<(String) -> Unit>(::foo)
|
||||
val x3 = ofType<(Int) -> Unit>(::<!NONE_APPLICABLE!>foo<!>)
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package
|
||||
|
||||
internal val x1: () -> kotlin.Unit
|
||||
internal val x2: (kotlin.String) -> kotlin.Unit
|
||||
internal val x3: (kotlin.Int) -> kotlin.Unit
|
||||
internal fun foo(): kotlin.Unit
|
||||
internal fun foo(/*0*/ s: kotlin.String): kotlin.Unit
|
||||
internal fun </*0*/ T> ofType(/*0*/ x: T): T
|
||||
@@ -0,0 +1,9 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun foo() {}
|
||||
fun foo(s: String) {}
|
||||
|
||||
val x1 = ::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>
|
||||
val x2: () -> Unit = ::foo
|
||||
val x3: (String) -> Unit = ::foo
|
||||
val x4: (Int) -> Unit = ::<!NONE_APPLICABLE!>foo<!>
|
||||
@@ -0,0 +1,8 @@
|
||||
package
|
||||
|
||||
internal val x1: [ERROR : Type for ::foo]
|
||||
internal val x2: () -> kotlin.Unit
|
||||
internal val x3: (kotlin.String) -> kotlin.Unit
|
||||
internal val x4: (kotlin.Int) -> kotlin.Unit
|
||||
internal fun foo(): kotlin.Unit
|
||||
internal fun foo(/*0*/ s: kotlin.String): kotlin.Unit
|
||||
@@ -0,0 +1,12 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
class Klass {
|
||||
constructor(a: Int) {}
|
||||
constructor(a: String) {}
|
||||
}
|
||||
|
||||
fun user(f: (Int) -> Klass) {}
|
||||
|
||||
fun fn() {
|
||||
user(::Klass)
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
internal fun fn(): kotlin.Unit
|
||||
internal fun user(/*0*/ f: (kotlin.Int) -> Klass): kotlin.Unit
|
||||
|
||||
internal final class Klass {
|
||||
public constructor Klass(/*0*/ a: kotlin.Int)
|
||||
public constructor Klass(/*0*/ a: kotlin.String)
|
||||
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,11 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
import kotlin.reflect.*
|
||||
|
||||
class A {
|
||||
val x = 1
|
||||
fun x() {}
|
||||
}
|
||||
|
||||
fun f1(): KProperty<Int> = A::x // ok, property
|
||||
fun f2(): (A) -> Unit = A::x // ok, function
|
||||
@@ -0,0 +1,13 @@
|
||||
package
|
||||
|
||||
internal fun f1(): kotlin.reflect.KProperty<kotlin.Int>
|
||||
internal fun f2(): (A) -> kotlin.Unit
|
||||
|
||||
internal final class A {
|
||||
public constructor A()
|
||||
internal final val x: kotlin.Int = 1
|
||||
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
|
||||
internal final fun x(): kotlin.Unit
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun foo() {}
|
||||
fun foo(s: String) {}
|
||||
|
||||
fun bar(f: () -> Unit) = 1
|
||||
fun bar(f: (String) -> Unit) = 2
|
||||
|
||||
val x1 = ::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!> as () -> Unit
|
||||
val x2 = bar(::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!> as (String) -> Unit)
|
||||
@@ -0,0 +1,8 @@
|
||||
package
|
||||
|
||||
internal val x1: () -> kotlin.Unit
|
||||
internal val x2: kotlin.Int
|
||||
internal fun bar(/*0*/ f: () -> kotlin.Unit): kotlin.Int
|
||||
internal fun bar(/*0*/ f: (kotlin.String) -> kotlin.Unit): kotlin.Int
|
||||
internal fun foo(): kotlin.Unit
|
||||
internal fun foo(/*0*/ s: kotlin.String): kotlin.Unit
|
||||
@@ -0,0 +1,28 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
import kotlin.reflect.*
|
||||
|
||||
fun <T> ofType(x: T): T = x
|
||||
|
||||
class A {
|
||||
val foo: Int = 0
|
||||
fun foo() {}
|
||||
|
||||
fun bar() {}
|
||||
val bar: Int = 0
|
||||
}
|
||||
|
||||
fun A.foo(): String = "A"
|
||||
|
||||
val x0 = A::foo // function A::foo wins by default
|
||||
val userOfX0 = x0(A())
|
||||
|
||||
val x1 = ofType<(A) -> Unit>(A::foo)
|
||||
val x2 = ofType<KProperty1<A, Int>>(A::foo)
|
||||
val x3: KProperty1<A, Int> = A::foo
|
||||
val x4: (A) -> String = A::foo
|
||||
|
||||
val y0 = A::bar
|
||||
val y1 = ofType<(A) -> Unit>(A::bar)
|
||||
val y2 = ofType<KProperty1<A, Int>>(A::bar)
|
||||
val y3: KProperty1<A, Int> = A::bar
|
||||
@@ -0,0 +1,25 @@
|
||||
package
|
||||
|
||||
internal val userOfX0: kotlin.Unit
|
||||
internal val x0: kotlin.reflect.KFunction1<A, kotlin.Unit>
|
||||
internal val x1: (A) -> kotlin.Unit
|
||||
internal val x2: kotlin.reflect.KProperty1<A, kotlin.Int>
|
||||
internal val x3: kotlin.reflect.KProperty1<A, kotlin.Int>
|
||||
internal val x4: (A) -> kotlin.String
|
||||
internal val y0: kotlin.reflect.KFunction1<A, kotlin.Unit>
|
||||
internal val y1: (A) -> kotlin.Unit
|
||||
internal val y2: kotlin.reflect.KProperty1<A, kotlin.Int>
|
||||
internal val y3: kotlin.reflect.KProperty1<A, kotlin.Int>
|
||||
internal fun </*0*/ T> ofType(/*0*/ x: T): T
|
||||
internal fun A.foo(): kotlin.String
|
||||
|
||||
internal final class A {
|
||||
public constructor A()
|
||||
internal final val bar: kotlin.Int = 0
|
||||
internal final val foo: kotlin.Int = 0
|
||||
internal final fun bar(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
internal final fun foo(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun <T, R> apply(x: T, f: (T) -> R): R = f(x)
|
||||
|
||||
fun foo(i: Int) {}
|
||||
fun foo(s: String) {}
|
||||
|
||||
val x1 = apply(1, ::foo)
|
||||
val x2 = apply("hello", ::foo)
|
||||
val x3 = apply(true, ::<!NONE_APPLICABLE!>foo<!>)
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package
|
||||
|
||||
internal val x1: kotlin.Unit
|
||||
internal val x2: kotlin.Unit
|
||||
internal val x3: [ERROR : Type for apply(true, ::foo)]
|
||||
internal fun </*0*/ T, /*1*/ R> apply(/*0*/ x: T, /*1*/ f: (T) -> R): R
|
||||
internal fun foo(/*0*/ i: kotlin.Int): kotlin.Unit
|
||||
internal fun foo(/*0*/ s: kotlin.String): kotlin.Unit
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER,-CONFLICTING_JVM_DECLARATIONS
|
||||
|
||||
fun foo(i: Int) = "$i"
|
||||
fun foo(s: String) = s
|
||||
|
||||
fun bar(s: String) = s
|
||||
|
||||
fun qux(i: Int, j: Int, k: Int): Int = i + j + k
|
||||
fun qux(a: String, b: String, c: String, d: String) {}
|
||||
|
||||
fun fn1(x: Int, f1: (Int) -> String, f2: (String) -> String) = f2(f1(x))
|
||||
|
||||
fun fn2(f1: (Int) -> String, f2: (String) -> String ) = f2(f1(0))
|
||||
fun fn2(f1: (Int) -> Int, f2: (Int) -> String ) = f2(f1(0))
|
||||
fun fn2(f1: (String) -> String, f2: (String) -> String ) = f2(f1(""))
|
||||
|
||||
fun fn3(i: Int, f: (Int, Int, Int) -> Int): Int = f(i, i, i)
|
||||
|
||||
val x1 = fn1(1, ::foo, ::foo)
|
||||
val x2 = fn1(1, ::foo, ::bar)
|
||||
|
||||
val x3 = fn2(::bar, ::foo)
|
||||
val x4 = fn2(::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>, ::bar)
|
||||
val x5 = fn2(::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>, ::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>)
|
||||
|
||||
val x6 = fn3(1, ::qux)
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package
|
||||
|
||||
internal val x1: kotlin.String
|
||||
internal val x2: kotlin.String
|
||||
internal val x3: kotlin.String
|
||||
internal val x4: [ERROR : Type for fn2(::foo, ::bar)]
|
||||
internal val x5: [ERROR : Type for fn2(::foo, ::foo)]
|
||||
internal val x6: kotlin.Int
|
||||
internal fun bar(/*0*/ s: kotlin.String): kotlin.String
|
||||
internal fun fn1(/*0*/ x: kotlin.Int, /*1*/ f1: (kotlin.Int) -> kotlin.String, /*2*/ f2: (kotlin.String) -> kotlin.String): kotlin.String
|
||||
internal fun fn2(/*0*/ f1: (kotlin.Int) -> kotlin.Int, /*1*/ f2: (kotlin.Int) -> kotlin.String): kotlin.String
|
||||
internal fun fn2(/*0*/ f1: (kotlin.Int) -> kotlin.String, /*1*/ f2: (kotlin.String) -> kotlin.String): kotlin.String
|
||||
internal fun fn2(/*0*/ f1: (kotlin.String) -> kotlin.String, /*1*/ f2: (kotlin.String) -> kotlin.String): kotlin.String
|
||||
internal fun fn3(/*0*/ i: kotlin.Int, /*1*/ f: (kotlin.Int, kotlin.Int, kotlin.Int) -> kotlin.Int): kotlin.Int
|
||||
internal fun foo(/*0*/ i: kotlin.Int): kotlin.String
|
||||
internal fun foo(/*0*/ s: kotlin.String): kotlin.String
|
||||
internal fun qux(/*0*/ i: kotlin.Int, /*1*/ j: kotlin.Int, /*2*/ k: kotlin.Int): kotlin.Int
|
||||
internal fun qux(/*0*/ a: kotlin.String, /*1*/ b: kotlin.String, /*2*/ c: kotlin.String, /*3*/ d: kotlin.String): kotlin.Unit
|
||||
@@ -0,0 +1,10 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
fun foo(vararg ii: Int) {}
|
||||
fun foo(vararg ss: String) {}
|
||||
fun foo(i: Int) {}
|
||||
|
||||
val fn1: (Int) -> Unit = ::foo
|
||||
val fn2: (IntArray) -> Unit = ::foo
|
||||
val fn3: (Int, Int) -> Unit = <!TYPE_MISMATCH!>::foo<!>
|
||||
val fn4: (Array<String>) -> Unit = ::foo
|
||||
@@ -0,0 +1,9 @@
|
||||
package
|
||||
|
||||
internal val fn1: (kotlin.Int) -> kotlin.Unit
|
||||
internal val fn2: (kotlin.IntArray) -> kotlin.Unit
|
||||
internal val fn3: (kotlin.Int, kotlin.Int) -> kotlin.Unit
|
||||
internal val fn4: (kotlin.Array<kotlin.String>) -> kotlin.Unit
|
||||
internal fun foo(/*0*/ vararg ss: kotlin.String /*kotlin.Array<out kotlin.String>*/): kotlin.Unit
|
||||
internal fun foo(/*0*/ i: kotlin.Int): kotlin.Unit
|
||||
internal fun foo(/*0*/ vararg ii: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit
|
||||
Reference in New Issue
Block a user