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:
Dmitry Petrov
2015-07-14 17:53:12 +03:00
parent b3a2ee2148
commit 6437a4bdc6
51 changed files with 1057 additions and 247 deletions
@@ -5,5 +5,5 @@ fun foo(<!UNUSED_PARAMETER!>x<!>: Any, y: Int) = y
fun main() {
::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>
val fooRef: (Int, Any) -> Unit = ::<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>
val fooRef: (Int, Any) -> Unit = ::<!NONE_APPLICABLE!>foo<!>
}
@@ -0,0 +1,22 @@
// FILE: A.kt
open class A<T>(val x: T)
// FILE: AFactory.kt
abstract class AFactory {
abstract fun create(): A<Int>?
}
// FILE: Util.kt
inline fun <reified T> createWith(x: T, f: (T) -> A<T>?)
= f(x)
// FILE: B.kt
class B(x: Int) : A<Int>(x) {
companion object : AFactory() {
override fun create(): A<Int>? = createWith(0, ::B)
}
}
@@ -0,0 +1,35 @@
package
kotlin.inline() internal fun </*0*/ reified T> createWith(/*0*/ x: T, /*1*/ f: (T) -> A<T>?): A<T>?
internal open class A</*0*/ T> {
public constructor A</*0*/ T>(/*0*/ x: T)
internal final val x: T
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 abstract class AFactory {
public constructor AFactory()
internal abstract fun create(): A<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
}
internal final class B : A<kotlin.Int> {
public constructor B(/*0*/ x: kotlin.Int)
internal final override /*1*/ /*fake_override*/ val x: 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 companion object Companion : AFactory {
private constructor Companion()
internal open override /*1*/ fun create(): A<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
}
}