K2: Fix priority for implicit receiver + extensionInvoke

See K1 counterpart at org.jetbrains.kotlin.resolve.calls.tower.TowerResolver.Task.processImplicitReceiver

^KT-58943 Fixed
^KT-59541 Fixed
This commit is contained in:
Denis.Zharkov
2023-05-26 18:35:24 +02:00
committed by Space Team
parent 1f120ecd20
commit 3279313f2c
24 changed files with 160 additions and 31 deletions
@@ -14,7 +14,7 @@ FILE: invokePriority.kt
String(1).R|<local>/foo|()
R|kotlin/with|<R|kotlin/String|, R|kotlin/Unit|>(String(2), <L> = with@fun R|kotlin/String|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=EXACTLY_ONCE> {
this@R|special/anonymous|.R|<local>/foo|()
R|<local>/foo|.R|SubstitutionOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(this@R|special/anonymous|)
}
)
}
@@ -4,7 +4,7 @@ class A {
fun String.foo(): Unit {} // (2)
"1".foo() // resolves to (2)
with("2") {
foo() // BUG: resolves to (1) in old FE, but to (2) in FIR
foo() // resolves to (1)
}
}
}
@@ -18557,6 +18557,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/fir/linkViaSignatures.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -18557,6 +18557,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/fir/linkViaSignatures.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -431,6 +431,7 @@ private class InvokeFunctionResolveTask(
val towerGroup =
TowerGroup
.Implicit(depth)
// see invokeExtensionVsOther2.kt test
.InvokeExtensionWithImplicitReceiver
.withGivenInvokeReceiverGroup(InvokeResolvePriority.INVOKE_EXTENSION)
@@ -37,13 +37,17 @@ sealed class TowerGroupKind(val index: Byte) : Comparable<TowerGroupKind> {
data object Member : TowerGroupKind(4)
class Local(depth: Int) : WithDepth(5, depth)
// If a variable of extension function type belong to some scope X, and there's an implicit receiver Y, then its invoke candidate
// should be less prioritized than the member scope of Y (see diagnostics/tests/resolve/priority/invokeExtensionVsOther2.kt),
// but more prioritized than extensions in X with bound receiver of Y (see analysis-tests/testData/resolveWithStdlib/problems/invokePriority.kt).
// That's why it's been places between Member and Local/ImplicitOrNonLocal.
data object InvokeExtensionWithImplicitReceiver : TowerGroupKind(5)
class ImplicitOrNonLocal(depth: Int, val kindForDebugSake: String) : WithDepth(6, depth)
class Local(depth: Int) : WithDepth(6, depth)
class ContextReceiverGroup(depth: Int) : WithDepth(7, depth)
class ImplicitOrNonLocal(depth: Int, val kindForDebugSake: String) : WithDepth(7, depth)
data object InvokeExtensionWithImplicitReceiver : TowerGroupKind(8)
class ContextReceiverGroup(depth: Int) : WithDepth(8, depth)
data object QualifierValue : TowerGroupKind(9)
@@ -198,6 +202,8 @@ private constructor(
val Member get() = kindOf(TowerGroupKind.Member)
val InvokeExtensionWithImplicitReceiver get() = kindOf(TowerGroupKind.InvokeExtensionWithImplicitReceiver)
fun Local(depth: Int) = kindOf(TowerGroupKind.Local(depth))
fun Implicit(depth: Int) = kindOf(TowerGroupKind.Implicit(depth))
@@ -205,8 +211,6 @@ private constructor(
fun ContextReceiverGroup(depth: Int) = kindOf(TowerGroupKind.ContextReceiverGroup(depth))
val InvokeExtensionWithImplicitReceiver get() = kindOf(TowerGroupKind.InvokeExtensionWithImplicitReceiver)
fun TopPrioritized(depth: Int) = kindOf(TowerGroupKind.TopPrioritized(depth))
fun InvokeReceiver(
@@ -1,10 +1,5 @@
// WITH_STDLIB
// IGNORE_BACKEND_K2: JVM_IR, JS_IR, NATIVE, WASM
// FIR status:
// java.lang.StackOverflowError
// at Nat$Companion$invoke$1.next(kt36853_fibonacci.kt:40) ...
fun box(): String {
Nat<Int>(
nil = 0,
@@ -0,0 +1,55 @@
// ISSUE: KT-59541
interface WriteContext {
val x: String
}
interface ReadContext {
val y: String
}
interface Codec<T> {
fun WriteContext.encode(value: T)
fun ReadContext.decode(): T?
}
fun <T> codec(
encode: WriteContext.(T) -> Unit,
decode: ReadContext.() -> T?
): Codec<T> = object : Codec<T> {
// Mostly, we check in this test that both `encode(value)` and `decode()` are resolved
// to the corresponding parameters of `codec` function (see KT-59541)
// Because before the fix for KT-37375, they both were resolved to the members of the anonymous objects
// leading to recursion and stack overflow.
override fun WriteContext.encode(value: T) = encode(value)
override fun ReadContext.decode(): T? = decode()
}
fun box(): String {
var result = ""
val t = codec(
{
result += x + it
},
{
y
}
)
with(t) {
object : WriteContext {
override val x: String
get() = "O"
}.encode("K")
result += object : ReadContext {
override val y: String
get() = "123"
}.decode()
}
if (result != "OK123") return "fail: $result"
return "OK"
}
@@ -1,16 +0,0 @@
// ISSUE: KT-58943
class A {
fun bar() {
val foo: String.() -> Int = { 1 } // (1)
fun String.foo(): String = "" // (2)
with("2") {
// In K1, foo variable + invokeExtension on implicit receiver is more prioritized than `foo() + implicit receiver`
// So, for now, we're going to preserve that behavior in K2
// For design, see KT-59528
takeInt(<!ARGUMENT_TYPE_MISMATCH!>foo()<!>)
}
}
}
fun takeInt(x: Int) {}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ISSUE: KT-58943
class A {
@@ -17699,6 +17699,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/fir/KotlinDocumentationProvider.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -18557,6 +18557,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/fir/linkViaSignatures.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -18557,6 +18557,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/fir/linkViaSignatures.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -15415,6 +15415,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/fir/linkViaSignatures.kt");
}
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
runTest("compiler/testData/codegen/box/fir/localOverrideWithDefaultInLocalOverridden.kt");
@@ -26,11 +26,11 @@ class Case1 {
this.<!DEBUG_INFO_CALL("fqName: Case1.bar.foo; typeCall: extension function")!>foo()<!> //resolves to (2)
}
"".run {
<!DEBUG_INFO_CALL("fqName: Case1.bar.foo; typeCall: extension function")!>foo()<!> //resolves to (1) !!!
<!DEBUG_INFO_CALL("fqName: kotlin.Function1.invoke; typeCall: variable&invoke")!>foo()<!> //resolves to (1) !!!
this.<!DEBUG_INFO_CALL("fqName: Case1.bar.foo; typeCall: extension function")!>foo()<!> //resolves to (2)
}
"".apply {
<!DEBUG_INFO_CALL("fqName: Case1.bar.foo; typeCall: extension function")!>foo()<!> //resolves to (1) !!!
<!DEBUG_INFO_CALL("fqName: kotlin.Function1.invoke; typeCall: variable&invoke")!>foo()<!> //resolves to (1) !!!
this.<!DEBUG_INFO_CALL("fqName: Case1.bar.foo; typeCall: extension function")!>foo()<!> //resolves to (2)
}
"".also {
@@ -13667,6 +13667,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -13667,6 +13667,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -13667,6 +13667,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -14773,6 +14773,12 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe
runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -15121,6 +15121,12 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB
runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -14600,6 +14600,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -14774,6 +14774,12 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT
runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -13643,6 +13643,12 @@ public class FirWasmCodegenBoxTestGenerated extends AbstractFirWasmCodegenBoxTes
runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {
@@ -13643,6 +13643,12 @@ public class K1WasmCodegenBoxTestGenerated extends AbstractK1WasmCodegenBoxTest
runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt");
}
@Test
@TestMetadata("localInvokeExtension.kt")
public void testLocalInvokeExtension() throws Exception {
runTest("compiler/testData/codegen/box/fir/localInvokeExtension.kt");
}
@Test
@TestMetadata("localOverrideWithDefaultInLocalOverridden.kt")
public void testLocalOverrideWithDefaultInLocalOverridden() throws Exception {