[FIR] Fix FP UNRESOLVED_REFERENCE on implicit invoke() after a safe call
`invoke()` function of functional types is always defined in such a way that its explicit receiver comes as the first value parameter. Extension-function types contain the very same `invoke` function, they just additionally have the `@ExtensionFunctionType` annotation. In the related test there is such an `invoke` function and in the presented call its explicit receiver is the anonymous function `fun Int.() = 1` itself. So the safe-checked `1` ^KT-60056
This commit is contained in:
committed by
Space Team
parent
502b422b6b
commit
e4781d8508
+13
-2
@@ -612,8 +612,19 @@ fun FirQualifiedAccessExpression.createSafeCall(receiver: FirExpression, source:
|
|||||||
}
|
}
|
||||||
this.source = receiver.source?.fakeElement(KtFakeSourceElementKind.CheckedSafeCallSubject)
|
this.source = receiver.source?.fakeElement(KtFakeSourceElementKind.CheckedSafeCallSubject)
|
||||||
}
|
}
|
||||||
|
// If an `invoke` function from a functional type expects a
|
||||||
replaceExplicitReceiver(checkedSafeCallSubject)
|
// receiver, it's still defined as the first value parameter.
|
||||||
|
// A construction like `1.(fun Int.() = 1)()` means we're calling
|
||||||
|
// `Function1<Int, Unit>.invoke(Int)`.
|
||||||
|
if (this is FirImplicitInvokeCall) {
|
||||||
|
val newArguments = buildArgumentList {
|
||||||
|
arguments.add(checkedSafeCallSubject)
|
||||||
|
arguments.addAll(this@createSafeCall.arguments)
|
||||||
|
}
|
||||||
|
replaceArgumentList(newArguments)
|
||||||
|
} else {
|
||||||
|
replaceExplicitReceiver(checkedSafeCallSubject)
|
||||||
|
}
|
||||||
return buildSafeCallExpression {
|
return buildSafeCallExpression {
|
||||||
this.receiver = receiver
|
this.receiver = receiver
|
||||||
@OptIn(FirContractViolation::class)
|
@OptIn(FirContractViolation::class)
|
||||||
|
|||||||
@@ -81,6 +81,6 @@ fun test() {
|
|||||||
val i : Int? = null
|
val i : Int? = null
|
||||||
i.<!UNSAFE_IMPLICIT_INVOKE_CALL!>(fun Int.() = 1)<!>();
|
i.<!UNSAFE_IMPLICIT_INVOKE_CALL!>(fun Int.() = 1)<!>();
|
||||||
<!INAPPLICABLE_CANDIDATE!>{}<!><Int>()
|
<!INAPPLICABLE_CANDIDATE!>{}<!><Int>()
|
||||||
1<!UNNECESSARY_SAFE_CALL!>?.<!>(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)()
|
1<!UNNECESSARY_SAFE_CALL!>?.<!>(fun Int.() = 1)()
|
||||||
1.<!NO_RECEIVER_ALLOWED!>{}<!>()
|
1.<!NO_RECEIVER_ALLOWED!>{}<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user