K2: add explicit cast to Any for Any function calls on stub types

This commit solves a stub type inconsistency problem.
As a part of KT-59369 fix we decided (see commit 299d2799),
that ConeStubTypeForChainInference has a scope of Any,
so we can safely resolve only to equals/hashCode/toString.
However, later we can replace a stub type with some inferred type,
which can have its own equals/hashCode/toString implementation,
while the call still refers Any member.
In this situation FIR2IR decides that we are calling a fake override,
which is not true, in fact we are calling an overriding method.
This leads to a crash in Native backend.

To solve this situation, we provide an explicit cast of a dispatch
receiver with a stub type (ConeStubTypeForChainInference) to Any,
thus confirming directly we are calling Any method and nothing else.

#KT-63932 Fixed
This commit is contained in:
Mikhail Glukhikh
2023-12-11 18:13:06 +01:00
committed by Space Team
parent a0deaea8fe
commit dbca7358af
13 changed files with 196 additions and 2 deletions
@@ -41067,6 +41067,18 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.kt");
}
@Test
@TestMetadata("stubCallOnReceiver.kt")
public void testStubCallOnReceiver() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/stubCallOnReceiver.kt");
}
@Test
@TestMetadata("stubCallOnVariable.kt")
public void testStubCallOnVariable() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/stubCallOnVariable.kt");
}
@Test
@TestMetadata("suspendCallsWithErrors.kt")
public void testSuspendCallsWithErrors() throws Exception {
@@ -41187,6 +41187,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.kt");
}
@Test
@TestMetadata("stubCallOnReceiver.kt")
public void testStubCallOnReceiver() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/stubCallOnReceiver.kt");
}
@Test
@TestMetadata("stubCallOnVariable.kt")
public void testStubCallOnVariable() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/stubCallOnVariable.kt");
}
@Test
@TestMetadata("suspendCallsWithErrors.kt")
public void testSuspendCallsWithErrors() throws Exception {
@@ -13,8 +13,11 @@ import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirOperation
import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression
import org.jetbrains.kotlin.fir.expressions.buildUnaryArgumentList
import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier
import org.jetbrains.kotlin.fir.expressions.builder.buildTypeOperatorCall
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
@@ -25,6 +28,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.FirImplicitAnyTypeRef
import org.jetbrains.kotlin.fir.utils.exceptions.withConeTypeEntry
import org.jetbrains.kotlin.name.StandardClassIds.Annotations.HidesMembers
import org.jetbrains.kotlin.types.AbstractTypeChecker
@@ -213,6 +217,15 @@ class MemberScopeTowerLevel(
val dispatchReceiverToUse = when {
isFromOriginalTypeInPresenceOfSmartCast ->
getOriginalReceiverExpressionIfStableSmartCast()
// For a chain inference stub in dispatch receiver, we have to provide an explicit cast to Any
// See KT-63932
dispatchReceiverValue.type is ConeStubTypeForChainInference -> buildTypeOperatorCall {
source = dispatchReceiverValue.receiverExpression.source?.fakeElement(KtFakeSourceElementKind.CastToAnyForStubTypes)
operation = FirOperation.AS
conversionTypeRef = FirImplicitAnyTypeRef(source)
argumentList = buildUnaryArgumentList(dispatchReceiverValue.receiverExpression)
coneTypeOrNull = session.builtinTypes.anyType.coneType
}
else -> dispatchReceiverValue.receiverExpression
}