Fix order of fixing type variables for callable references. KT-25433 Fixed

This commit is contained in:
Dmitriy Novozhilov
2019-02-27 18:02:13 +03:00
parent 735f86a50e
commit 7072b9d179
7 changed files with 75 additions and 0 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.LHSArgumentConstraintPosition
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForLambdaReturnType
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.types.UnwrappedType
@@ -141,6 +142,14 @@ private fun preprocessCallableReference(
val notCallableTypeConstructor =
csBuilder.getProperSuperTypeConstructors(expectedType).firstOrNull { !ReflectionTypes.isPossibleExpectedCallableType(it) }
argument.lhsResult.safeAs<LHSResult.Type>()?.let {
val lhsType = it.unboundDetailedReceiver.stableType
if (ReflectionTypes.isNumberedTypeWithOneOrMoreNumber(expectedType)) {
val lhsTypeVariable = expectedType.arguments.first().type.unwrap()
csBuilder.addSubtypeConstraint(lhsType, lhsTypeVariable, LHSArgumentConstraintPosition(it.qualifier))
}
}
if (notCallableTypeConstructor != null) {
diagnosticsHolder.addDiagnostic(NotCallableExpectedType(argument, expectedType, notCallableTypeConstructor))
}
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.INAPPLICABLE
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
@@ -55,6 +56,12 @@ class KnownTypeParameterConstraintPosition(val typeArgument: KotlinType) : Const
override fun toString() = "TypeArgument $typeArgument"
}
class LHSArgumentConstraintPosition(val receiver: QualifierReceiver) : ConstraintPosition() {
override fun toString(): String {
return "LHS receiver $receiver"
}
}
class LambdaArgumentConstraintPosition(val lambda: ResolvedLambdaAtom) : ConstraintPosition() {
override fun toString(): String {
return "LambdaArgument $lambda"
@@ -0,0 +1,17 @@
// !WITH_NEW_INFERENCE
// !DIAGNOSTICS: -UNUSED_PARAMETER
// Issue: KT-25433
import kotlin.reflect.*
fun <T, R> hidden(nameProp: KProperty1<T, R>, value: R) {}
fun <T, R> hiddenFun(nameFunc: KFunction1<T, R>, value: R) {}
class App(val nullable: String?) {
fun nullableFun(): String? = null
}
fun test() {
hidden(App::nullable, "foo")
hiddenFun(App::nullableFun, "foo")
}
@@ -0,0 +1,14 @@
package
public fun </*0*/ T, /*1*/ R> hidden(/*0*/ nameProp: kotlin.reflect.KProperty1<T, R>, /*1*/ value: R): kotlin.Unit
public fun </*0*/ T, /*1*/ R> hiddenFun(/*0*/ nameFunc: kotlin.reflect.KFunction1<T, R>, /*1*/ value: R): kotlin.Unit
public fun test(): kotlin.Unit
public final class App {
public constructor App(/*0*/ nullable: kotlin.String?)
public final val nullable: 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 final fun nullableFun(): kotlin.String?
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1681,6 +1681,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/callableReference/kt15439_completeCall.kt");
}
@TestMetadata("kt25433.kt")
public void testKt25433() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/kt25433.kt");
}
@TestMetadata("kt7430_wrongClassOnLHS.kt")
public void testKt7430_wrongClassOnLHS() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/kt7430_wrongClassOnLHS.kt");
@@ -1676,6 +1676,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/callableReference/kt15439_completeCall.kt");
}
@TestMetadata("kt25433.kt")
public void testKt25433() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/kt25433.kt");
}
@TestMetadata("kt7430_wrongClassOnLHS.kt")
public void testKt7430_wrongClassOnLHS() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/kt7430_wrongClassOnLHS.kt");
@@ -18,9 +18,13 @@ import org.jetbrains.kotlin.types.*
import kotlin.reflect.KProperty
val KOTLIN_REFLECT_FQ_NAME = FqName("kotlin.reflect")
val K_PROPERTY_PREFIX = "KProperty"
val K_MUTABLE_PROPERTY_PREFIX = "KMutableProperty"
val K_FUNCTION_PREFIX = "KFunction"
val K_SUSPEND_FUNCTION_PREFIX = "KSuspendFunction"
val PREFIXES = listOf(K_PROPERTY_PREFIX, K_MUTABLE_PROPERTY_PREFIX, K_FUNCTION_PREFIX, K_SUSPEND_FUNCTION_PREFIX)
class ReflectionTypes(module: ModuleDescriptor, private val notFoundClasses: NotFoundClasses) {
private val kotlinReflectScope: MemberScope by lazy(LazyThreadSafetyMode.PUBLICATION) {
module.getPackage(KOTLIN_REFLECT_FQ_NAME).memberScope
@@ -122,6 +126,20 @@ class ReflectionTypes(module: ModuleDescriptor, private val notFoundClasses: Not
hasFqName(descriptor, KotlinBuiltIns.FQ_NAMES.kMutableProperty2)
}
fun isNumberedTypeWithOneOrMoreNumber(type: KotlinType): Boolean {
val descriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return false
if (DescriptorUtils.getFqName(descriptor).parent().toSafe() != KOTLIN_REFLECT_FQ_NAME) return false
val shortName = descriptor.name.asString()
for (prefix in PREFIXES) {
if (shortName.startsWith(prefix)) {
val number = shortName.removePrefix(prefix)
return number.isNotEmpty() && number != "0"
}
}
return false
}
fun hasKPropertyTypeFqName(type: KotlinType): Boolean =
hasFqName(type.constructor, KotlinBuiltIns.FQ_NAMES.kPropertyFqName)