[FIR] Expand expected types before ILT approximation

^KT-56176 Fixed
This commit is contained in:
Dmitriy Novozhilov
2023-01-25 15:45:29 +02:00
committed by Space Team
parent 4941fcd10e
commit a084bcbbb5
11 changed files with 98 additions and 3 deletions
@@ -2648,6 +2648,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/firProblems/InnerClassInAnonymous.kt");
}
@Test
@TestMetadata("integerLiteralWithExpectedTypealiasType.kt")
public void testIntegerLiteralWithExpectedTypealiasType() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/integerLiteralWithExpectedTypealiasType.kt");
}
@Test
@TestMetadata("internalPotentialFakeOverride.kt")
public void testInternalPotentialFakeOverride() throws Exception {
@@ -2648,6 +2648,12 @@ public class LightTreeFir2IrTextTestGenerated extends AbstractLightTreeFir2IrTex
runTest("compiler/testData/ir/irText/firProblems/InnerClassInAnonymous.kt");
}
@Test
@TestMetadata("integerLiteralWithExpectedTypealiasType.kt")
public void testIntegerLiteralWithExpectedTypealiasType() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/integerLiteralWithExpectedTypealiasType.kt");
}
@Test
@TestMetadata("internalPotentialFakeOverride.kt")
public void testInternalPotentialFakeOverride() throws Exception {
@@ -695,7 +695,7 @@ class FirCallCompletionResultsWriterTransformer(
val finalType = finalSubstitutor.substituteOrNull(initialType)
var resultType = block.resultType.withReplacedConeType(finalType)
resultType.coneTypeSafe<ConeIntegerLiteralType>()?.let {
resultType = resultType.resolvedTypeFromPrototype(it.getApproximatedType(data?.getExpectedType(block)))
resultType = resultType.resolvedTypeFromPrototype(it.getApproximatedType(data?.getExpectedType(block)?.fullyExpandedType(session)))
}
block.replaceTypeRef(resultType)
session.lookupTracker?.recordTypeResolveAsLookup(resultType, block.source, context.file.source)
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedErrorReference
import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.scope
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
@@ -64,7 +65,7 @@ class IntegerLiteralAndOperatorApproximationTransformer(
data: ConeKotlinType?
): FirStatement {
val type = constExpression.resultType.coneTypeSafe<ConeIntegerLiteralType>() ?: return constExpression
val approximatedType = type.getApproximatedType(data)
val approximatedType = type.getApproximatedType(data?.fullyExpandedType(session))
constExpression.resultType = constExpression.resultType.resolvedTypeFromPrototype(approximatedType)
@Suppress("UNCHECKED_CAST")
val kind = approximatedType.toConstKind() as ConstantValueKind<T>
@@ -79,7 +80,7 @@ class IntegerLiteralAndOperatorApproximationTransformer(
@Suppress("UnnecessaryVariable")
val call = integerLiteralOperatorCall
val operatorType = call.resultType.coneTypeSafe<ConeIntegerLiteralType>() ?: return call
val approximatedType = operatorType.getApproximatedType(data)
val approximatedType = operatorType.getApproximatedType(data?.fullyExpandedType(session))
call.transformDispatchReceiver(this, null)
call.transformExtensionReceiver(this, null)
call.argumentList.transformArguments(this, null)
@@ -0,0 +1,20 @@
FILE fqName:<root> fileName:/integerLiteralWithExpectedTypealiasType.kt
TYPEALIAS name:MyLong visibility:public expandedType:kotlin.Long
FUN name:foo visibility:public modality:FINAL <> (l:kotlin.Long) returnType:kotlin.String
VALUE_PARAMETER name:l index:0 type:kotlin.Long
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun foo (l: kotlin.Long): kotlin.String declared in <root>'
WHEN type=kotlin.String origin=IF
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'l: kotlin.Long declared in <root>.foo' type=kotlin.Long origin=null
arg1: CONST Long type=kotlin.Long value=0
then: CONST String type=kotlin.String value="OK"
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST String type=kotlin.String value="fail"
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
CALL 'public final fun foo (l: kotlin.Long): kotlin.String declared in <root>' type=kotlin.String origin=null
l: CONST Long type=kotlin.Long value=0
@@ -0,0 +1,11 @@
typealias MyLong = Long
fun foo(l: Long): String {
return when {
EQEQ(arg0 = l, arg1 = 0L) -> "OK"
else -> "fail"
}
}
fun box(): String {
return foo(l = 0L)
}
@@ -0,0 +1,20 @@
FILE fqName:<root> fileName:/integerLiteralWithExpectedTypealiasType.kt
TYPEALIAS name:MyLong visibility:public expandedType:kotlin.Long
FUN name:foo visibility:public modality:FINAL <> (l:kotlin.Long{ <root>.MyLong }) returnType:kotlin.String
VALUE_PARAMETER name:l index:0 type:kotlin.Long{ <root>.MyLong }
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun foo (l: kotlin.Long{ <root>.MyLong }): kotlin.String declared in <root>'
WHEN type=kotlin.String origin=IF
BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'l: kotlin.Long{ <root>.MyLong } declared in <root>.foo' type=kotlin.Long{ <root>.MyLong } origin=null
arg1: CONST Long type=kotlin.Long value=0
then: CONST String type=kotlin.String value="OK"
BRANCH
if: CONST Boolean type=kotlin.Boolean value=true
then: CONST String type=kotlin.String value="fail"
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
CALL 'public final fun foo (l: kotlin.Long{ <root>.MyLong }): kotlin.String declared in <root>' type=kotlin.String origin=null
l: CONST Long type=kotlin.Long value=0
@@ -0,0 +1,9 @@
// ISSUE: KT-56176
typealias MyLong = Long
fun foo(l: MyLong): String {
return if (l == 0L) "OK" else "fail"
}
fun box(): String = foo(0)
@@ -0,0 +1,11 @@
typealias MyLong = Long
fun foo(l: Long): String {
return when {
EQEQ(arg0 = l, arg1 = 0L) -> "OK"
else -> "fail"
}
}
fun box(): String {
return foo(l = 0L)
}
@@ -2648,6 +2648,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest {
runTest("compiler/testData/ir/irText/firProblems/InnerClassInAnonymous.kt");
}
@Test
@TestMetadata("integerLiteralWithExpectedTypealiasType.kt")
public void testIntegerLiteralWithExpectedTypealiasType() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/integerLiteralWithExpectedTypealiasType.kt");
}
@Test
@TestMetadata("internalPotentialFakeOverride.kt")
public void testInternalPotentialFakeOverride() throws Exception {
@@ -1950,6 +1950,11 @@ public class KlibTextTestCaseGenerated extends AbstractKlibTextTestCase {
runTest("compiler/testData/ir/irText/firProblems/InnerClassInAnonymous.kt");
}
@TestMetadata("integerLiteralWithExpectedTypealiasType.kt")
public void testIntegerLiteralWithExpectedTypealiasType() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/integerLiteralWithExpectedTypealiasType.kt");
}
@TestMetadata("kt43342.kt")
public void testKt43342() throws Exception {
runTest("compiler/testData/ir/irText/firProblems/kt43342.kt");