[FIR] Handle default parameters when checking callable reference type
#KT-36759 Fixed
This commit is contained in:
@@ -230,7 +230,10 @@ internal object CheckCallableReferenceExpectedType : CheckerStage() {
|
||||
val returnTypeRef = candidate.bodyResolveComponents.returnTypeCalculator.tryCalculateReturnType(fir)
|
||||
|
||||
val resultingType: ConeKotlinType = when (fir) {
|
||||
is FirFunction -> createKFunctionType(fir, resultingReceiverType, returnTypeRef)
|
||||
is FirFunction -> createKFunctionType(
|
||||
fir, resultingReceiverType, returnTypeRef,
|
||||
expectedParameterNumberWithReceiver = expectedType?.let { it.typeArguments.size - 1 }
|
||||
)
|
||||
is FirVariable<*> -> createKPropertyType(fir, resultingReceiverType, returnTypeRef)
|
||||
else -> ConeKotlinErrorType("Unknown callable kind: ${fir::class}")
|
||||
}.let(candidate.substitutor::substituteOrSelf)
|
||||
@@ -284,10 +287,20 @@ private fun createKPropertyType(
|
||||
private fun createKFunctionType(
|
||||
function: FirFunction<*>,
|
||||
receiverType: ConeKotlinType?,
|
||||
returnTypeRef: FirResolvedTypeRef
|
||||
returnTypeRef: FirResolvedTypeRef,
|
||||
expectedParameterNumberWithReceiver: Int?
|
||||
): ConeKotlinType {
|
||||
val parameterTypes = function.valueParameters.map {
|
||||
it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: ConeKotlinErrorType("No type for parameter $it")
|
||||
val parameterTypes = mutableListOf<ConeKotlinType>()
|
||||
val expectedParameterNumber = when {
|
||||
expectedParameterNumberWithReceiver == null -> null
|
||||
receiverType != null -> expectedParameterNumberWithReceiver - 1
|
||||
else -> expectedParameterNumberWithReceiver
|
||||
}
|
||||
for ((index, valueParameter) in function.valueParameters.withIndex()) {
|
||||
if (expectedParameterNumber == null || index < expectedParameterNumber || valueParameter.defaultValue == null) {
|
||||
parameterTypes += valueParameter.returnTypeRef.coneTypeSafe()
|
||||
?: ConeKotlinErrorType("No type for parameter $valueParameter")
|
||||
}
|
||||
}
|
||||
|
||||
return createFunctionalType(
|
||||
|
||||
+1
-1
@@ -5,5 +5,5 @@ class A {
|
||||
inline fun <T> T.myLet(block: (T) -> Unit) {}
|
||||
|
||||
fun test(a: A, s: String) {
|
||||
s.<!INAPPLICABLE_CANDIDATE!>myLet<!>(a::foo)
|
||||
s.myLet(a::foo)
|
||||
}
|
||||
+1
-1
@@ -11,5 +11,5 @@ FILE: callableReferencesAndDefaultParameters.kt
|
||||
public final inline fun <T> R|T|.myLet(block: R|(T) -> kotlin/Unit|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun test(a: R|A|, s: R|kotlin/String|): R|kotlin/Unit| {
|
||||
R|<local>/s|.<Inapplicable(INAPPLICABLE): [/myLet]>#(R|<local>/a|::R|/A.foo|)
|
||||
R|<local>/s|.R|/myLet|<R|kotlin/String|>(R|<local>/a|::R|/A.foo|)
|
||||
}
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
fun foo(x: String, y: String = "K"): String = x + y
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
inline fun String.app(f: (String) -> String) = f(this)
|
||||
|
||||
|
||||
+1
-1
@@ -13,6 +13,6 @@ fun bar2(body: (String, Int) -> String): String {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
<!INAPPLICABLE_CANDIDATE!>bar1<!>(::foo)
|
||||
bar1(::foo)
|
||||
bar2(::foo)
|
||||
}
|
||||
+1
-1
@@ -13,6 +13,6 @@ fun bar2(body: (String, Int) -> String): String {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
<!INAPPLICABLE_CANDIDATE!>bar1<!>(::foo)
|
||||
bar1(::foo)
|
||||
bar2(::foo)
|
||||
}
|
||||
+1
-1
@@ -26,5 +26,5 @@ fun test() {
|
||||
|
||||
<!UNRESOLVED_REFERENCE!>B::bas<!>
|
||||
|
||||
<!UNRESOLVED_REFERENCE!>::fas<!>
|
||||
::fas
|
||||
}
|
||||
+5
-5
@@ -47,11 +47,11 @@ FILE fqName:<root> fileName:/withAdaptedArguments.kt
|
||||
overridden:
|
||||
public open fun toString (): kotlin.String declared in kotlin.Any
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
|
||||
FUN name:testDefault visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
FUN name:testDefault visibility:public modality:FINAL <> () returnType:kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun testDefault (): IrErrorType declared in <root>'
|
||||
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/use]>#' type=IrErrorType
|
||||
FUNCTION_REFERENCE 'public final fun fnWithDefault (a: kotlin.Int, b: kotlin.Int): kotlin.String declared in <root>' type=kotlin.reflect.KFunction2<kotlin.Int, kotlin.Int, kotlin.String> origin=null reflectionTarget=<same>
|
||||
RETURN type=kotlin.Nothing from='public final fun testDefault (): kotlin.String declared in <root>'
|
||||
CALL 'public final fun use (fn: kotlin.Function1<kotlin.Int, kotlin.String>): kotlin.String declared in <root>' type=kotlin.String origin=null
|
||||
fn: FUNCTION_REFERENCE 'public final fun fnWithDefault (a: kotlin.Int, b: kotlin.Int): kotlin.String declared in <root>' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.String> origin=null reflectionTarget=<same>
|
||||
FUN name:testVararg visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun testVararg (): IrErrorType declared in <root>'
|
||||
@@ -61,7 +61,7 @@ FILE fqName:<root> fileName:/withAdaptedArguments.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun testCoercionToUnit (): IrErrorType declared in <root>'
|
||||
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/coerceToUnit]>#' type=IrErrorType
|
||||
FUNCTION_REFERENCE 'public final fun fnWithDefault (a: kotlin.Int, b: kotlin.Int): kotlin.String declared in <root>' type=kotlin.reflect.KFunction2<kotlin.Int, kotlin.Int, kotlin.String> origin=null reflectionTarget=<same>
|
||||
FUNCTION_REFERENCE 'public final fun fnWithDefault (a: kotlin.Int, b: kotlin.Int): kotlin.String declared in <root>' type=kotlin.reflect.KFunction1<kotlin.Int, kotlin.String> origin=null reflectionTarget=<same>
|
||||
FUN name:testImportedObjectMember visibility:public modality:FINAL <> () returnType:IrErrorType
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='public final fun testImportedObjectMember (): IrErrorType declared in <root>'
|
||||
|
||||
+2
-2
@@ -72,5 +72,5 @@ FILE fqName:<root> fileName:/withVarargViewedAsArray.kt
|
||||
FUNCTION_REFERENCE 'public final fun nsum (vararg args: kotlin.Number): kotlin.Int declared in <root>' type=kotlin.reflect.KFunction1<kotlin.Array<kotlin.Number>, kotlin.Int> origin=null reflectionTarget=<same>
|
||||
FUN name:testArrayAndDefaults visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
ERROR_CALL 'Unresolved reference: <Inapplicable(INAPPLICABLE): [/useStringArray]>#' type=IrErrorType
|
||||
FUNCTION_REFERENCE 'public final fun zap (vararg b: kotlin.String, k: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction2<kotlin.Array<kotlin.String>, kotlin.Int, kotlin.Unit> origin=null reflectionTarget=<same>
|
||||
CALL 'public final fun useStringArray (fn: kotlin.Function1<kotlin.Array<kotlin.String>, kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
|
||||
fn: FUNCTION_REFERENCE 'public final fun zap (vararg b: kotlin.String, k: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.reflect.KFunction1<kotlin.Array<kotlin.String>, kotlin.Unit> origin=null reflectionTarget=<same>
|
||||
|
||||
Reference in New Issue
Block a user