Fix exception when expected type is subtype of a function type
#KT-28984 Fixed #EA-132850 Fixed
This commit is contained in:
+9
-2
@@ -434,7 +434,7 @@ class GenericCandidateResolver(
|
||||
expectedType?.isSuspendFunctionType == true
|
||||
)
|
||||
}
|
||||
if (expectedType == null || !expectedType.isBuiltinFunctionalTypeOrSubtype || hasUnknownFunctionParameter(expectedType)) {
|
||||
if (expectedType == null || !expectedType.isBuiltinFunctionalType || hasUnknownFunctionParameter(expectedType)) {
|
||||
return
|
||||
}
|
||||
val dataFlowInfoForArguments = context.candidateCall.dataFlowInfoForArguments
|
||||
@@ -491,7 +491,7 @@ class GenericCandidateResolver(
|
||||
val effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument, context)
|
||||
val expectedType = getExpectedTypeForCallableReference(callableReference, constraintSystem, context, effectiveExpectedType)
|
||||
?: return
|
||||
if (!ReflectionTypes.isCallableType(expectedType)) return
|
||||
if (!expectedType.isApplicableExpectedTypeForCallableReference()) return
|
||||
val resolvedType = getResolvedTypeForCallableReference(callableReference, context, expectedType, valueArgument) ?: return
|
||||
val position = VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.index)
|
||||
constraintSystem.addSubtypeConstraint(
|
||||
@@ -555,3 +555,10 @@ fun makeConstantSubstitutor(typeParameterDescriptors: Collection<TypeParameterDe
|
||||
override fun isEmpty() = false
|
||||
})
|
||||
}
|
||||
|
||||
private fun KotlinType.isApplicableExpectedTypeForCallableReference(): Boolean {
|
||||
return this.isFunctionType ||
|
||||
ReflectionTypes.isBaseTypeForNumberedReferenceTypes(this) ||
|
||||
ReflectionTypes.isNumberedKFunctionOrKSuspendFunction(this) ||
|
||||
ReflectionTypes.isNumberedKPropertyOrKMutablePropertyType(this)
|
||||
}
|
||||
+1
-6
@@ -350,7 +350,7 @@ fun extractInputOutputTypesFromCallableReferenceExpectedType(expectedType: Unwra
|
||||
expectedType.isFunctionType ->
|
||||
extractInputOutputTypesFromFunctionType(expectedType)
|
||||
|
||||
expectedType.isBaseTypeForNumberedReferenceTypes() ->
|
||||
ReflectionTypes.isBaseTypeForNumberedReferenceTypes(expectedType) ->
|
||||
InputOutputTypes(emptyList(), expectedType.arguments.single().type.unwrap())
|
||||
|
||||
ReflectionTypes.isNumberedKFunctionOrKSuspendFunction(expectedType) -> {
|
||||
@@ -367,11 +367,6 @@ fun extractInputOutputTypesFromCallableReferenceExpectedType(expectedType: Unwra
|
||||
}
|
||||
}
|
||||
|
||||
private fun UnwrappedType.isBaseTypeForNumberedReferenceTypes(): Boolean =
|
||||
ReflectionTypes.hasKPropertyTypeFqName(this) ||
|
||||
ReflectionTypes.hasKMutablePropertyTypeFqName(this) ||
|
||||
ReflectionTypes.hasKCallableTypeFqName(this)
|
||||
|
||||
private fun extractInputOutputTypesFromFunctionType(functionType: UnwrappedType): InputOutputTypes {
|
||||
val receiver = functionType.getReceiverTypeFromFunctionType()?.unwrap()
|
||||
val parameters = functionType.getValueParameterTypesFromFunctionType().map { it.type.unwrap() }
|
||||
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
abstract class SubFunction : kotlin.Function0<Unit>
|
||||
|
||||
fun <T> takeIt(x: T, f: SubFunction) {}
|
||||
|
||||
fun cr() {}
|
||||
|
||||
fun test() {
|
||||
<!TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>takeIt<!>(42, <!TYPE_MISMATCH!>::cr<!>)
|
||||
<!TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>takeIt<!>(42, <!TYPE_MISMATCH!>{ }<!>)
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
package
|
||||
|
||||
public fun cr(): kotlin.Unit
|
||||
public fun </*0*/ T> takeIt(/*0*/ x: T, /*1*/ f: SubFunction): kotlin.Unit
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
public abstract class SubFunction : () -> kotlin.Unit {
|
||||
public constructor SubFunction()
|
||||
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 abstract override /*1*/ /*fake_override*/ fun invoke(): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -1651,6 +1651,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/emptyLhs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("expectedTypeAsSubtypeOfFunctionType.kt")
|
||||
public void testExpectedTypeAsSubtypeOfFunctionType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/expectedTypeAsSubtypeOfFunctionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt15439_completeCall.kt")
|
||||
public void testKt15439_completeCall() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/kt15439_completeCall.kt");
|
||||
|
||||
Generated
+5
@@ -1651,6 +1651,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/emptyLhs.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("expectedTypeAsSubtypeOfFunctionType.kt")
|
||||
public void testExpectedTypeAsSubtypeOfFunctionType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/expectedTypeAsSubtypeOfFunctionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt15439_completeCall.kt")
|
||||
public void testKt15439_completeCall() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/kt15439_completeCall.kt");
|
||||
|
||||
@@ -97,6 +97,11 @@ class ReflectionTypes(module: ModuleDescriptor, private val notFoundClasses: Not
|
||||
fun isCallableType(type: KotlinType): Boolean =
|
||||
type.isFunctionTypeOrSubtype || type.isSuspendFunctionTypeOrSubtype || isKCallableType(type)
|
||||
|
||||
fun isBaseTypeForNumberedReferenceTypes(type: KotlinType): Boolean =
|
||||
ReflectionTypes.hasKPropertyTypeFqName(type) ||
|
||||
ReflectionTypes.hasKMutablePropertyTypeFqName(type) ||
|
||||
ReflectionTypes.hasKCallableTypeFqName(type)
|
||||
|
||||
@JvmStatic
|
||||
fun isNumberedKPropertyOrKMutablePropertyType(type: KotlinType): Boolean =
|
||||
isNumberedKPropertyType(type) || isNumberedKMutablePropertyType(type)
|
||||
|
||||
Reference in New Issue
Block a user