[FIR2IR] Expand typealiases before inserting implicit casts
^KT-59461 Fixed ^KT-59464
This commit is contained in:
committed by
Space Team
parent
8a1372e21c
commit
2581139b82
+18
-12
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirUnitExpression
|
|||||||
import org.jetbrains.kotlin.fir.references.FirReference
|
import org.jetbrains.kotlin.fir.references.FirReference
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
||||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||||
@@ -197,7 +198,7 @@ class Fir2IrImplicitCastInserter(
|
|||||||
|
|
||||||
// ==================================================================================
|
// ==================================================================================
|
||||||
|
|
||||||
internal fun IrExpression.cast(expression: FirExpression, valueType: FirTypeRef, expectedType: FirTypeRef): IrExpression {
|
internal fun IrExpression.cast(expression: FirExpression, valueTypeRef: FirTypeRef, expectedTypeRef: FirTypeRef): IrExpression {
|
||||||
if (this is IrTypeOperatorCall) {
|
if (this is IrTypeOperatorCall) {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -206,12 +207,15 @@ class Fir2IrImplicitCastInserter(
|
|||||||
insertImplicitCasts()
|
insertImplicitCasts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val valueType = valueTypeRef.coneTypeSafe<ConeKotlinType>()?.fullyExpandedType(session) ?: return this
|
||||||
|
val expectedType = expectedTypeRef.coneTypeSafe<ConeKotlinType>()?.fullyExpandedType(session) ?: return this
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
expectedType.isUnit -> {
|
expectedType.isUnit -> {
|
||||||
coerceToUnitIfNeeded(this, irBuiltIns)
|
coerceToUnitIfNeeded(this, irBuiltIns)
|
||||||
}
|
}
|
||||||
valueType.coneTypeSafe<ConeDynamicType>() != null -> {
|
valueType is ConeDynamicType -> {
|
||||||
if (expectedType.coneType !is ConeDynamicType && !expectedType.isNullableAny) {
|
if (expectedType !is ConeDynamicType && !expectedType.isNullableAny) {
|
||||||
implicitCast(this, expectedType.toIrType(ConversionTypeContext.DEFAULT))
|
implicitCast(this, expectedType.toIrType(ConversionTypeContext.DEFAULT))
|
||||||
} else {
|
} else {
|
||||||
this
|
this
|
||||||
@@ -226,8 +230,9 @@ class Fir2IrImplicitCastInserter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirTypeRef.acceptsNullValues(): Boolean =
|
private fun ConeKotlinType.acceptsNullValues(): Boolean {
|
||||||
canBeNull || hasEnhancedNullability()
|
return canBeNull || hasEnhancedNullability
|
||||||
|
}
|
||||||
|
|
||||||
private fun IrExpression.insertImplicitNotNullCastIfNeeded(expression: FirExpression): IrExpression {
|
private fun IrExpression.insertImplicitNotNullCastIfNeeded(expression: FirExpression): IrExpression {
|
||||||
if (this is IrGetEnumValue) return this
|
if (this is IrGetEnumValue) return this
|
||||||
@@ -365,17 +370,18 @@ class Fir2IrImplicitCastInserter(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun typeCanBeEnhancedOrFlexibleNullable(typeRef: FirTypeRef): Boolean {
|
internal fun typeCanBeEnhancedOrFlexibleNullable(type: ConeKotlinType): Boolean {
|
||||||
return when {
|
return when {
|
||||||
typeRef.hasEnhancedNullability() -> true
|
type.hasEnhancedNullability -> true
|
||||||
typeRef.isNullabilityFlexible() && typeRef.canBeNull -> true
|
type.hasFlexibleNullability && type.canBeNull -> true
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirTypeRef.isNullabilityFlexible(): Boolean {
|
private val ConeKotlinType.hasFlexibleNullability: Boolean
|
||||||
val flexibility = coneTypeSafe<ConeFlexibleType>() ?: return false
|
get() {
|
||||||
return flexibility.lowerBound.isMarkedNullable != flexibility.upperBound.isMarkedNullable
|
if (this !is ConeFlexibleType) return false
|
||||||
}
|
return lowerBound.isMarkedNullable != upperBound.isMarkedNullable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -53,7 +53,7 @@ class DelegatedMemberGenerator(private val components: Fir2IrComponents) : Fir2I
|
|||||||
|
|
||||||
fun generateBodies() {
|
fun generateBodies() {
|
||||||
for ((declaration, irField, delegateToSymbol, delegateToLookupTag) in bodiesInfo) {
|
for ((declaration, irField, delegateToSymbol, delegateToLookupTag) in bodiesInfo) {
|
||||||
val callTypeCanBeNullable = Fir2IrImplicitCastInserter.typeCanBeEnhancedOrFlexibleNullable(delegateToSymbol.fir.returnTypeRef)
|
val callTypeCanBeNullable = Fir2IrImplicitCastInserter.typeCanBeEnhancedOrFlexibleNullable(delegateToSymbol.fir.returnTypeRef.coneType.fullyExpandedType(session))
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is IrSimpleFunction -> {
|
is IrSimpleFunction -> {
|
||||||
val member = declarationStorage.getIrFunctionSymbol(
|
val member = declarationStorage.getIrFunctionSymbol(
|
||||||
|
|||||||
+6
@@ -18489,6 +18489,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
|||||||
runTest("compiler/testData/codegen/box/fir/flexibleIntegerLiterals.kt");
|
runTest("compiler/testData/codegen/box/fir/flexibleIntegerLiterals.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("flexibleStaticConstantFromJava.kt")
|
||||||
|
public void testFlexibleStaticConstantFromJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/fir/flexibleStaticConstantFromJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("getOnNullableTypeAlias.kt")
|
@TestMetadata("getOnNullableTypeAlias.kt")
|
||||||
public void testGetOnNullableTypeAlias() throws Exception {
|
public void testGetOnNullableTypeAlias() throws Exception {
|
||||||
|
|||||||
+6
@@ -18489,6 +18489,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
|||||||
runTest("compiler/testData/codegen/box/fir/flexibleIntegerLiterals.kt");
|
runTest("compiler/testData/codegen/box/fir/flexibleIntegerLiterals.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("flexibleStaticConstantFromJava.kt")
|
||||||
|
public void testFlexibleStaticConstantFromJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/fir/flexibleStaticConstantFromJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("getOnNullableTypeAlias.kt")
|
@TestMetadata("getOnNullableTypeAlias.kt")
|
||||||
public void testGetOnNullableTypeAlias() throws Exception {
|
public void testGetOnNullableTypeAlias() throws Exception {
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// ISSUE: KT-59461
|
||||||
|
|
||||||
|
// FILE: NullContainer.java
|
||||||
|
public interface NullContainer {
|
||||||
|
static String NULL = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
typealias NullableString = String?
|
||||||
|
|
||||||
|
fun updateThreadContext(): NullableString {
|
||||||
|
return NullContainer.NULL
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
updateThreadContext()
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+6
@@ -17667,6 +17667,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/fir/flexibleIntegerLiterals.kt");
|
runTest("compiler/testData/codegen/box/fir/flexibleIntegerLiterals.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("flexibleStaticConstantFromJava.kt")
|
||||||
|
public void testFlexibleStaticConstantFromJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/fir/flexibleStaticConstantFromJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("incorrectBytecodeWithEnhancedNullability.kt")
|
@TestMetadata("incorrectBytecodeWithEnhancedNullability.kt")
|
||||||
public void testIncorrectBytecodeWithEnhancedNullability() throws Exception {
|
public void testIncorrectBytecodeWithEnhancedNullability() throws Exception {
|
||||||
|
|||||||
+6
@@ -18489,6 +18489,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/fir/flexibleIntegerLiterals.kt");
|
runTest("compiler/testData/codegen/box/fir/flexibleIntegerLiterals.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("flexibleStaticConstantFromJava.kt")
|
||||||
|
public void testFlexibleStaticConstantFromJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/fir/flexibleStaticConstantFromJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("getOnNullableTypeAlias.kt")
|
@TestMetadata("getOnNullableTypeAlias.kt")
|
||||||
public void testGetOnNullableTypeAlias() throws Exception {
|
public void testGetOnNullableTypeAlias() throws Exception {
|
||||||
|
|||||||
+6
@@ -18489,6 +18489,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
|||||||
runTest("compiler/testData/codegen/box/fir/flexibleIntegerLiterals.kt");
|
runTest("compiler/testData/codegen/box/fir/flexibleIntegerLiterals.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("flexibleStaticConstantFromJava.kt")
|
||||||
|
public void testFlexibleStaticConstantFromJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/fir/flexibleStaticConstantFromJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("getOnNullableTypeAlias.kt")
|
@TestMetadata("getOnNullableTypeAlias.kt")
|
||||||
public void testGetOnNullableTypeAlias() throws Exception {
|
public void testGetOnNullableTypeAlias() throws Exception {
|
||||||
|
|||||||
+5
@@ -14673,6 +14673,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/fir/flexibleIntegerLiterals.kt");
|
runTest("compiler/testData/codegen/box/fir/flexibleIntegerLiterals.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("flexibleStaticConstantFromJava.kt")
|
||||||
|
public void testFlexibleStaticConstantFromJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/fir/flexibleStaticConstantFromJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("incorrectBytecodeWithEnhancedNullability.kt")
|
@TestMetadata("incorrectBytecodeWithEnhancedNullability.kt")
|
||||||
public void testIncorrectBytecodeWithEnhancedNullability() throws Exception {
|
public void testIncorrectBytecodeWithEnhancedNullability() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/fir/incorrectBytecodeWithEnhancedNullability.kt");
|
runTest("compiler/testData/codegen/box/fir/incorrectBytecodeWithEnhancedNullability.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user