Fix compiler exception during resolution of ambiguous callable references

Function return type can't and should not be used during overload resolution of callable references.
Since it can be DeferredType, its substitution in CS caused exception.
This commit is contained in:
Pavel Kirpichenkov
2019-10-17 18:33:38 +03:00
parent 8b97819c04
commit 138d558f6a
7 changed files with 78 additions and 3 deletions
@@ -16,8 +16,8 @@
package org.jetbrains.kotlin.resolve.calls.results
import org.jetbrains.kotlin.builtins.getAllParameterProjectionsFromCallableReflectionType
import org.jetbrains.kotlin.container.DefaultImplementation
import org.jetbrains.kotlin.container.PlatformExtensionsClashResolver
import org.jetbrains.kotlin.container.PlatformSpecificExtension
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.MemberDescriptor
@@ -62,7 +62,7 @@ class FlatSignature<out T> constructor(
return FlatSignature(
origin,
descriptor.typeParameters,
reflectionType.arguments.map { it.type }, // should we drop return type?
reflectionType.getAllParameterProjectionsFromCallableReflectionType().map { it.type },
hasExtensionReceiver = false,
hasVarargs = descriptor.valueParameters.any { it.varargElementType != null },
numDefaults = numDefaults,
@@ -0,0 +1,16 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
// !WITH_NEW_INFERENCE
interface G<T> {
fun build(): G<T>
}
class V1<V>(val value: V)
class V2<V>(val value: V)
fun <V, T : V?> G<T>.foo(vararg values: V1<V>) = build()
fun <V, T : V?> G<T>.foo(vararg values: V2<V?>) = build()
fun forReference(ref: Any?) {}
fun test() {
forReference(G<Int?>::<!NI;CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY, NI;DEBUG_INFO_MISSING_UNRESOLVED, OI;CANNOT_COMPLETE_RESOLVE!>foo<!>)
}
@@ -0,0 +1,29 @@
package
public fun forReference(/*0*/ ref: kotlin.Any?): kotlin.Unit
public fun test(): kotlin.Unit
public fun </*0*/ V, /*1*/ T : V?> G<T>.foo(/*0*/ vararg values: V1<V> /*kotlin.Array<out V1<V>>*/): G<T>
public fun </*0*/ V, /*1*/ T : V?> G<T>.foo(/*0*/ vararg values: V2<V?> /*kotlin.Array<out V2<V?>>*/): G<T>
public interface G</*0*/ T> {
public abstract fun build(): G<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
}
public final class V1</*0*/ V> {
public constructor V1</*0*/ V>(/*0*/ value: V)
public final val value: V
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 V2</*0*/ V> {
public constructor V2</*0*/ V>(/*0*/ value: V)
public final val value: V
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,12 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
// !LANGUAGE: +NewInference
// !WITH_NEW_INFERENCE
fun foo(s: String) {}
fun foo(i: Long) {}
fun bar(f: (Boolean) -> Unit) {}
fun test() {
bar(::<!NI;CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY, NI;DEBUG_INFO_MISSING_UNRESOLVED, OI;NONE_APPLICABLE!>foo<!>)
}
@@ -0,0 +1,6 @@
package
public fun bar(/*0*/ f: (kotlin.Boolean) -> kotlin.Unit): kotlin.Unit
public fun foo(/*0*/ i: kotlin.Long): kotlin.Unit
public fun foo(/*0*/ s: kotlin.String): kotlin.Unit
public fun test(): kotlin.Unit
@@ -112,7 +112,7 @@ class ReflectionTypes(module: ModuleDescriptor, private val notFoundClasses: Not
fun isNumberedKPropertyOrKMutablePropertyType(type: KotlinType): Boolean =
isNumberedKPropertyType(type) || isNumberedKMutablePropertyType(type)
private fun isKCallableType(type: KotlinType): Boolean =
fun isKCallableType(type: KotlinType): Boolean =
hasKCallableTypeFqName(type) || type.constructor.supertypes.any { isKCallableType(it) }
fun hasKCallableTypeFqName(type: KotlinType): Boolean =
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.*
private fun KotlinType.isTypeOrSubtypeOf(predicate: (KotlinType) -> Boolean): Boolean =
@@ -58,6 +59,9 @@ val KotlinType.isFunctionType: Boolean
val KotlinType.isSuspendFunctionType: Boolean
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionClassDescriptor.Kind.SuspendFunction
val KotlinType.isCallableReflectionType: Boolean
get() = ReflectionTypes.isKCallableType(this)
val KotlinType.isKSuspendFunctionType: Boolean
get() = constructor.declarationDescriptor?.getFunctionalClassKind() == FunctionClassDescriptor.Kind.KSuspendFunction
@@ -139,6 +143,14 @@ fun KotlinType.getValueParameterTypesFromFunctionType(): List<TypeProjection> {
return arguments.subList(first, last)
}
fun KotlinType.getAllParameterProjectionsFromCallableReflectionType(): List<TypeProjection> {
assert(isCallableReflectionType) { "Not a callable reflection type: $this" }
val arguments = arguments
val last = arguments.size - 1
assert(last >= 0) { "Unexpected number of type arguments in type: $this" }
return arguments.subList(0, last)
}
fun KotlinType.extractParameterNameFromFunctionTypeArgument(): Name? {
val annotation = annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.parameterName) ?: return null
val name = (annotation.allValueArguments.values.singleOrNull() as? StringValue)