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:
committed by
Space Team
parent
1f120ecd20
commit
3279313f2c
+1
-1
@@ -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|)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+1
@@ -431,6 +431,7 @@ private class InvokeFunctionResolveTask(
|
||||
val towerGroup =
|
||||
TowerGroup
|
||||
.Implicit(depth)
|
||||
// see invokeExtensionVsOther2.kt test
|
||||
.InvokeExtensionWithImplicitReceiver
|
||||
.withGivenInvokeReceiverGroup(InvokeResolvePriority.INVOKE_EXTENSION)
|
||||
|
||||
|
||||
+10
-6
@@ -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"
|
||||
}
|
||||
Vendored
-16
@@ -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
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KT-58943
|
||||
|
||||
class A {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+5
@@ -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");
|
||||
|
||||
+2
-2
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
Generated
+6
@@ -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 {
|
||||
|
||||
Generated
+6
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user