[FIR] Fix tower priorities for invoke resolve
#KT-45316 Fixed
This commit is contained in:
+5
@@ -750,6 +750,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/syntheticPropertiesWrongImplicitReceiver.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/syntheticPropertiesWrongImplicitReceiver.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("twoLocalLambdasWithSameName.kt")
|
||||||
|
public void testTwoLocalLambdasWithSameName() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/twoLocalLambdasWithSameName.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("typeAliasWithNotNullBound.kt")
|
@TestMetadata("typeAliasWithNotNullBound.kt")
|
||||||
public void testTypeAliasWithNotNullBound() throws Exception {
|
public void testTypeAliasWithNotNullBound() throws Exception {
|
||||||
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/typeAliasWithNotNullBound.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/typeAliasWithNotNullBound.kt");
|
||||||
|
|||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
FILE: twoLocalLambdasWithSameName.kt
|
||||||
|
public abstract interface R : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public final fun takeInt(x: R|kotlin/Int|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun test(fn: R|R.() -> kotlin/String|): R|kotlin/Unit| {
|
||||||
|
lval renderer: R|<anonymous>| = object : R|R| {
|
||||||
|
private constructor(): R|<anonymous>| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun render(fn: R|R.() -> kotlin/Int|): R|kotlin/Unit| {
|
||||||
|
lval result: R|kotlin/Int| = R|<local>/fn|.R|SubstitutionOverride<kotlin/Function1.invoke: R|kotlin/Int|>|(this@R|/<anonymous>|)
|
||||||
|
R|/takeInt|(R|<local>/result|)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// ISSUE: KT-45316
|
||||||
|
interface R
|
||||||
|
|
||||||
|
fun takeInt(x: Int) {}
|
||||||
|
|
||||||
|
fun test(fn: R.() -> String) { // (1)
|
||||||
|
val renderer = object : R {
|
||||||
|
fun render(fn: R.() -> Int) { // (2)
|
||||||
|
val result = fn()
|
||||||
|
takeInt(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -869,6 +869,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/syntheticPropertiesWrongImplicitReceiver.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/syntheticPropertiesWrongImplicitReceiver.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("twoLocalLambdasWithSameName.kt")
|
||||||
|
public void testTwoLocalLambdasWithSameName() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/twoLocalLambdasWithSameName.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("typeAliasWithNotNullBound.kt")
|
@TestMetadata("typeAliasWithNotNullBound.kt")
|
||||||
public void testTypeAliasWithNotNullBound() throws Exception {
|
public void testTypeAliasWithNotNullBound() throws Exception {
|
||||||
|
|||||||
+6
@@ -876,6 +876,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
|||||||
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/syntheticPropertiesWrongImplicitReceiver.kt");
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/syntheticPropertiesWrongImplicitReceiver.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("twoLocalLambdasWithSameName.kt")
|
||||||
|
public void testTwoLocalLambdasWithSameName() throws Exception {
|
||||||
|
runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/twoLocalLambdasWithSameName.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("typeAliasWithNotNullBound.kt")
|
@TestMetadata("typeAliasWithNotNullBound.kt")
|
||||||
public void testTypeAliasWithNotNullBound() throws Exception {
|
public void testTypeAliasWithNotNullBound() throws Exception {
|
||||||
|
|||||||
+5
-2
@@ -331,8 +331,11 @@ private class InvokeFunctionResolveTask(
|
|||||||
candidateFactory,
|
candidateFactory,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun interceptTowerGroup(towerGroup: TowerGroup): TowerGroup =
|
override fun interceptTowerGroup(towerGroup: TowerGroup): TowerGroup {
|
||||||
maxOf(towerGroup.InvokeResolvePriority(InvokeResolvePriority.COMMON_INVOKE), receiverGroup)
|
val invokeGroup = towerGroup.InvokeResolvePriority(InvokeResolvePriority.COMMON_INVOKE)
|
||||||
|
val max = maxOf(invokeGroup, receiverGroup)
|
||||||
|
return max.InvokeReceiver(receiverGroup)
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun runResolverForInvoke(
|
suspend fun runResolverForInvoke(
|
||||||
info: CallInfo,
|
info: CallInfo,
|
||||||
|
|||||||
+19
-3
@@ -70,7 +70,8 @@ class TowerGroup
|
|||||||
private constructor(
|
private constructor(
|
||||||
private val code: Long,
|
private val code: Long,
|
||||||
private val debugKinds: Array<TowerGroupKind>,
|
private val debugKinds: Array<TowerGroupKind>,
|
||||||
private val invokeResolvePriority: InvokeResolvePriority = InvokeResolvePriority.NONE
|
private val invokeResolvePriority: InvokeResolvePriority = InvokeResolvePriority.NONE,
|
||||||
|
private val receiverGroup: TowerGroup? = null
|
||||||
) : Comparable<TowerGroup> {
|
) : Comparable<TowerGroup> {
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@@ -183,6 +184,8 @@ private constructor(
|
|||||||
|
|
||||||
fun TopPrioritized(depth: Int) = kindOf(TowerGroupKind.TopPrioritized(depth))
|
fun TopPrioritized(depth: Int) = kindOf(TowerGroupKind.TopPrioritized(depth))
|
||||||
|
|
||||||
|
fun InvokeReceiver(receiverGroup: TowerGroup) = TowerGroup(code, debugKinds, invokeResolvePriority, receiverGroup)
|
||||||
|
|
||||||
// Treating `a.foo()` common calls as more prioritized than `a.foo.invoke()`
|
// Treating `a.foo()` common calls as more prioritized than `a.foo.invoke()`
|
||||||
// It's not the same as TowerGroupKind because it's not about tower levels, but rather a different dimension semantically.
|
// It's not the same as TowerGroupKind because it's not about tower levels, but rather a different dimension semantically.
|
||||||
// It could be implemented via another TowerGroupKind, but it's not clear what priority should be assigned to the new TowerGroupKind
|
// It could be implemented via another TowerGroupKind, but it's not clear what priority should be assigned to the new TowerGroupKind
|
||||||
@@ -203,13 +206,23 @@ private constructor(
|
|||||||
}
|
}
|
||||||
if (index < other.debugKinds.size) return -1
|
if (index < other.debugKinds.size) return -1
|
||||||
|
|
||||||
return invokeResolvePriority.compareTo(other.invokeResolvePriority)
|
val actualResult = invokeResolvePriority.compareTo(other.invokeResolvePriority)
|
||||||
|
if (actualResult == 0) {
|
||||||
|
return if (receiverGroup == null || other.receiverGroup == null) 0
|
||||||
|
else receiverGroup.debugCompareTo(other.receiverGroup)
|
||||||
|
}
|
||||||
|
return actualResult
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun compareTo(other: TowerGroup): Int = run {
|
override fun compareTo(other: TowerGroup): Int = run {
|
||||||
val result = java.lang.Long.compareUnsigned(code, other.code)
|
val result = java.lang.Long.compareUnsigned(code, other.code)
|
||||||
if (result != 0) return@run result
|
if (result != 0) return@run result
|
||||||
return@run invokeResolvePriority.compareTo(other.invokeResolvePriority)
|
val actualResult = invokeResolvePriority.compareTo(other.invokeResolvePriority)
|
||||||
|
if (actualResult == 0) {
|
||||||
|
return@run if (receiverGroup == null || other.receiverGroup == null) 0
|
||||||
|
else receiverGroup.compareTo(other.receiverGroup)
|
||||||
|
}
|
||||||
|
return@run actualResult
|
||||||
}.also {
|
}.also {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
val debugResult = debugCompareTo(other)
|
val debugResult = debugCompareTo(other)
|
||||||
@@ -226,6 +239,9 @@ private constructor(
|
|||||||
if (code != other.code) return false
|
if (code != other.code) return false
|
||||||
if (DEBUG) require(this.debugKinds.contentEquals(other.debugKinds)) { "Equals inconsistent: $this vs $other" }
|
if (DEBUG) require(this.debugKinds.contentEquals(other.debugKinds)) { "Equals inconsistent: $this vs $other" }
|
||||||
if (invokeResolvePriority != other.invokeResolvePriority) return false
|
if (invokeResolvePriority != other.invokeResolvePriority) return false
|
||||||
|
if (receiverGroup != null && other.receiverGroup != null) {
|
||||||
|
if (receiverGroup != other.receiverGroup) return false
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user