IR: support smart cast values in RangeContainsLowering
#KT-44878 Fixed
This commit is contained in:
+6
@@ -28097,6 +28097,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/rangeContainsString.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartCastOnBothEnds.kt")
|
||||
public void testSmartCastOnBothEnds() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/smartCastOnBothEnds.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("userDefinedContainsExtension.kt")
|
||||
public void testUserDefinedContainsExtension() throws Exception {
|
||||
|
||||
+20
-15
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.backend.common.lower.loops.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.loops.handlers.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.matchers.SimpleCalleeMatcher
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.andand
|
||||
import org.jetbrains.kotlin.ir.builders.irBlock
|
||||
@@ -29,6 +31,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -361,26 +364,28 @@ private class Transformer(
|
||||
}
|
||||
|
||||
private fun leastCommonPrimitiveNumericType(symbols: Symbols<CommonBackendContext>, t1: IrType, t2: IrType): IrType? {
|
||||
val pt1 = t1.promoteIntegerTypeToIntIfRequired(symbols)
|
||||
val pt2 = t2.promoteIntegerTypeToIntIfRequired(symbols)
|
||||
val primitive1 = t1.getPrimitiveType()
|
||||
val primitive2 = t2.getPrimitiveType()
|
||||
val unsigned1 = t1.getUnsignedType()
|
||||
val unsigned2 = t2.getUnsignedType()
|
||||
|
||||
return when {
|
||||
pt1.isDouble() || pt2.isDouble() -> symbols.double
|
||||
pt1.isFloat() || pt2.isFloat() -> symbols.float
|
||||
pt1.isULong() || pt2.isULong() -> symbols.uLong!!
|
||||
pt1.isUInt() || pt2.isUInt() -> symbols.uInt!!
|
||||
pt1.isLong() || pt2.isLong() -> symbols.long
|
||||
pt1.isInt() || pt2.isInt() -> symbols.int
|
||||
pt1.isChar() || pt2.isChar() -> symbols.char
|
||||
else -> error("Unexpected types: t1=${t1.classOrNull?.owner?.name}, t2=${t2.classOrNull?.owner?.name}")
|
||||
primitive1 == PrimitiveType.DOUBLE || primitive2 == PrimitiveType.DOUBLE -> symbols.double
|
||||
primitive1 == PrimitiveType.FLOAT || primitive2 == PrimitiveType.FLOAT -> symbols.float
|
||||
unsigned1 == UnsignedType.ULONG || unsigned2 == UnsignedType.ULONG -> symbols.uLong!!
|
||||
unsigned1.isPromotableToUInt() || unsigned2.isPromotableToUInt() -> symbols.uInt!!
|
||||
primitive1 == PrimitiveType.LONG || primitive2 == PrimitiveType.LONG -> symbols.long
|
||||
primitive1.isPromotableToInt() || primitive2.isPromotableToInt() -> symbols.int
|
||||
primitive1 == PrimitiveType.CHAR || primitive2 == PrimitiveType.CHAR -> symbols.char
|
||||
else -> error("Unexpected types: t1=${t1.render()}, t2=${t2.render()}")
|
||||
}.defaultType
|
||||
}
|
||||
|
||||
private fun IrType.promoteIntegerTypeToIntIfRequired(symbols: Symbols<CommonBackendContext>): IrType = when {
|
||||
isByte() || isShort() -> symbols.int.defaultType
|
||||
isUByte() || isUShort() -> symbols.uInt!!.defaultType
|
||||
else -> this
|
||||
}
|
||||
private fun PrimitiveType?.isPromotableToInt(): Boolean =
|
||||
this == PrimitiveType.INT || this == PrimitiveType.SHORT || this == PrimitiveType.BYTE
|
||||
|
||||
private fun UnsignedType?.isPromotableToUInt(): Boolean =
|
||||
this == UnsignedType.UINT || this == UnsignedType.USHORT || this == UnsignedType.UBYTE
|
||||
}
|
||||
|
||||
internal open class RangeHeaderInfoBuilder(context: CommonBackendContext, scopeOwnerSymbol: () -> IrSymbol) :
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
// Fails on the old JVM backend because of KT-42017.
|
||||
// IGNORE_BACKEND: JVM
|
||||
|
||||
fun checkDouble(a: Double?, b: Double?, c: Double): Boolean = a != null && b != null && c !in a..b
|
||||
fun checkFloat(a: Float?, b: Float?, c: Float): Boolean = a != null && b != null && c !in a..b
|
||||
fun checkLong(a: Long?, b: Long?, c: Long): Boolean = a != null && b != null && c !in a..b
|
||||
fun checkInt(a: Int?, b: Int?, c: Int): Boolean = a != null && b != null && c !in a..b
|
||||
fun checkChar(a: Char?, b: Char?, c: Char): Boolean = a != null && b != null && c !in a..b
|
||||
fun checkByte(a: Byte?, b: Byte?, c: Byte): Boolean = a != null && b != null && c !in a..b
|
||||
fun checkShort(a: Short?, b: Short?, c: Short): Boolean = a != null && b != null && c !in a..b
|
||||
fun checkUInt(a: UInt?, b: UInt?, c: UInt): Boolean = a != null && b != null && c !in a..b
|
||||
fun checkULong(a: ULong?, b: ULong?, c: ULong): Boolean = a != null && b != null && c !in a..b
|
||||
fun checkUByte(a: UByte?, b: UByte?, c: UByte): Boolean = a != null && b != null && c !in a..b
|
||||
fun checkUShort(a: UShort?, b: UShort?, c: UShort): Boolean = a != null && b != null && c !in a..b
|
||||
|
||||
fun box(): String {
|
||||
if (!checkDouble(1.0, 2.0, 0.0)) return "Fail Double"
|
||||
if (!checkFloat(1.0f, 2.0f, 0.0f)) return "Fail Float"
|
||||
if (!checkLong(1L, 2L, 0L)) return "Fail Long"
|
||||
if (!checkInt(1, 2, 0)) return "Fail Int"
|
||||
if (!checkChar('1', '2', '0')) return "Fail Char"
|
||||
if (!checkByte(1.toByte(), 2.toByte(), 0.toByte())) return "Fail Byte"
|
||||
if (!checkShort(1.toShort(), 2.toShort(), 0.toShort())) return "Fail Short"
|
||||
if (!checkUInt(1u, 2u, 0u)) return "Fail UInt"
|
||||
if (!checkULong(1UL, 2UL, 0UL)) return "Fail ULong"
|
||||
if (!checkUByte(1u, 2u, 0u)) return "Fail UByte"
|
||||
if (!checkUShort(1u, 2u, 0u)) return "Fail UShort"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -28097,6 +28097,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/rangeContainsString.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartCastOnBothEnds.kt")
|
||||
public void testSmartCastOnBothEnds() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/smartCastOnBothEnds.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("userDefinedContainsExtension.kt")
|
||||
public void testUserDefinedContainsExtension() throws Exception {
|
||||
|
||||
+6
@@ -28097,6 +28097,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/rangeContainsString.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("smartCastOnBothEnds.kt")
|
||||
public void testSmartCastOnBothEnds() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/smartCastOnBothEnds.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("userDefinedContainsExtension.kt")
|
||||
public void testUserDefinedContainsExtension() throws Exception {
|
||||
|
||||
+5
@@ -23747,6 +23747,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Contains extends AbstractLightAnalysisModeTest {
|
||||
@TestMetadata("smartCastOnBothEnds.kt")
|
||||
public void ignoreSmartCastOnBothEnds() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/smartCastOnBothEnds.kt");
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+5
@@ -19165,6 +19165,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/rangeContainsString.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("smartCastOnBothEnds.kt")
|
||||
public void testSmartCastOnBothEnds() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/smartCastOnBothEnds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("userDefinedContainsExtension.kt")
|
||||
public void testUserDefinedContainsExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/userDefinedContainsExtension.kt");
|
||||
|
||||
Generated
+5
@@ -18650,6 +18650,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/rangeContainsString.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("smartCastOnBothEnds.kt")
|
||||
public void testSmartCastOnBothEnds() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/smartCastOnBothEnds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("userDefinedContainsExtension.kt")
|
||||
public void testUserDefinedContainsExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/userDefinedContainsExtension.kt");
|
||||
|
||||
Generated
+5
@@ -18700,6 +18700,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/rangeContainsString.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("smartCastOnBothEnds.kt")
|
||||
public void testSmartCastOnBothEnds() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/smartCastOnBothEnds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("userDefinedContainsExtension.kt")
|
||||
public void testUserDefinedContainsExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/userDefinedContainsExtension.kt");
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+5
@@ -11937,6 +11937,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/rangeContainsString.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("smartCastOnBothEnds.kt")
|
||||
public void testSmartCastOnBothEnds() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/smartCastOnBothEnds.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("userDefinedContainsExtension.kt")
|
||||
public void testUserDefinedContainsExtension() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/contains/userDefinedContainsExtension.kt");
|
||||
|
||||
Reference in New Issue
Block a user