[FIR] Properly set isReceiver for implicit invoke on function types

This commit is contained in:
Nikolay Lunyak
2023-11-28 12:01:34 +02:00
committed by Space Team
parent 2bd77d5cdc
commit c69c34ff8b
11 changed files with 21 additions and 45 deletions
@@ -471,12 +471,17 @@ internal object CheckArguments : CheckerStage() {
candidate.symbol.lazyResolveToPhase(FirResolvePhase.STATUS)
val argumentMapping =
candidate.argumentMapping ?: error("Argument should be already mapped while checking arguments!")
for (argument in callInfo.arguments) {
val isInvokeFromExtensionFunctionType = candidate.explicitReceiverKind == DISPATCH_RECEIVER
&& candidate.dispatchReceiver?.resolvedType?.isExtensionFunctionType == true
&& (candidate.symbol as? FirNamedFunctionSymbol)?.name == OperatorNameConventions.INVOKE
for ((index, argument) in callInfo.arguments.withIndex()) {
candidate.resolveArgument(
callInfo,
argument,
argumentMapping[argument],
isReceiver = false,
isReceiver = index == 0 && isInvokeFromExtensionFunctionType,
sink = sink,
context = context
)
@@ -2,6 +2,6 @@ fun bar(doIt: Int.() -> Int) {
1.doIt()
1<!UNNECESSARY_SAFE_CALL!>?.<!>doIt()
val i: Int? = 1
<!ARGUMENT_TYPE_MISMATCH!>i<!>.doIt()
i.<!UNSAFE_IMPLICIT_INVOKE_CALL!>doIt<!>()
i?.doIt()
}
@@ -77,9 +77,9 @@ fun main1() {
fun test() {
{x : Int -> 1}<!NO_VALUE_FOR_PARAMETER!>()<!>;
(fun Int.() = 1)<!NO_VALUE_FOR_PARAMETER!>()<!>
<!ARGUMENT_TYPE_MISMATCH!>"sd"<!>.(fun Int.() = 1)()
"sd".<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>(fun Int.() = 1)<!>()
val i : Int? = null
<!ARGUMENT_TYPE_MISMATCH!>i<!>.(fun Int.() = 1)();
i.<!UNSAFE_IMPLICIT_INVOKE_CALL!>(fun Int.() = 1)<!>();
<!INAPPLICABLE_CANDIDATE!>{}<!><Int>()
1<!UNNECESSARY_SAFE_CALL!>?.<!>(<!UNRESOLVED_REFERENCE!>fun Int.() = 1<!>)()
1.<!NO_RECEIVER_ALLOWED!>{}<!>()
@@ -34,7 +34,7 @@ fun test4() {
// should be an error on receiver, shouldn't be thrown away
fun test5() {
<!ARGUMENT_TYPE_MISMATCH!>1<!>.(fun String.()=1)()
1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>(fun String.()=1)<!>()
}
fun <R: Any> R?.sure() : R = this!!
@@ -12,7 +12,7 @@ fun test(f: Runnable.(Int) -> Unit, runnable: Runnable) {
fun Int.test(f: String.(Int) -> Unit) {
f("", 0)
<!ARGUMENT_TYPE_MISMATCH!>f<!>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
f(<!NO_VALUE_FOR_PARAMETER!>"")<!>
with("") {
f(0)
f(<!ARGUMENT_TYPE_MISMATCH!>0.0<!>)
@@ -1,30 +0,0 @@
// KT-5362 Compiler crashes on access to extension method from nested class
class Outer {
class Nested{
fun foo(s: String) = s.<!UNRESOLVED_REFERENCE!>extension<!>()
}
private fun String.extension(): String = this
}
// EA-64302 - UOE: CodegenContext.getOuterExpression
fun Activity.toast() = Unit
class Activity(){
class Fragment{
fun call() = <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>toast<!>()
}
}
// KT-8814 No error in IDE for invalid invoke of OuterClass.()->Unit in static nested class
public class Manager {
fun task(callback: Manager.() -> Unit): Task {
val task = Task(callback)
return task
}
class Task(val callback: Manager.() -> Unit) : Runnable {
override public fun run() {
<!ARGUMENT_TYPE_MISMATCH!>callback<!>() // Manager is not accessible here, but no error is shown
}
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// KT-5362 Compiler crashes on access to extension method from nested class
class Outer {
class Nested{
@@ -1,16 +1,16 @@
fun test1() {
<!ARGUMENT_TYPE_MISMATCH!>1<!>. (fun String.(i: Int) = i )(1)
<!ARGUMENT_TYPE_MISMATCH!>1<!>.(label@ fun String.(i: Int) = i )(1)
1. <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>(fun String.(i: Int) = i )<!>(1)
1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>(label@ fun String.(i: Int) = i )<!>(1)
}
fun test2(f: String.(Int) -> Unit) {
<!ARGUMENT_TYPE_MISMATCH!>11<!>.(f)(1)
<!ARGUMENT_TYPE_MISMATCH!>11<!>.(f)<!NO_VALUE_FOR_PARAMETER!>()<!>
11.(<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>f<!>)(1)
11.(f)<!NO_VALUE_FOR_PARAMETER!>()<!>
}
fun test3() {
fun foo(): String.(Int) -> Unit = {}
<!ARGUMENT_TYPE_MISMATCH!>1<!>.(foo())(1)
1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>(foo())<!>(1)
}
@@ -9,5 +9,5 @@ fun test(identifier: SomeClass, fn: String.() -> Unit) {
<!NONE_APPLICABLE!>identifier<!>()
<!NONE_APPLICABLE!>identifier<!>(123)
<!OPERATOR_MODIFIER_REQUIRED!>identifier<!>(<!ARGUMENT_TYPE_MISMATCH!>1<!>, <!TOO_MANY_ARGUMENTS!>2<!>)
<!ARGUMENT_TYPE_MISMATCH!>1<!>.fn()
1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>fn<!>()
}
@@ -16,7 +16,7 @@ fun test(a: A, b: B) {
b.(foo)()
<!ARGUMENT_TYPE_MISMATCH!>(b.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>foo<!>)()<!>
(b.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>foo<!>)<!NO_VALUE_FOR_PARAMETER!>()<!>
foo(b)
(foo)(b)
@@ -8,5 +8,5 @@ fun test(identifier: SomeClass, fn: String.() -> Unit) {
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>identifier<!>()
<!OPERATOR_MODIFIER_REQUIRED!>identifier<!>(<!TOO_MANY_ARGUMENTS!>123<!>)
<!OPERATOR_MODIFIER_REQUIRED!>identifier<!>(<!TOO_MANY_ARGUMENTS!>1<!>, <!TOO_MANY_ARGUMENTS!>2<!>)
<!ARGUMENT_TYPE_MISMATCH!>1<!>.fn()
1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>fn<!>()
}