From bf844aa8e4021e1de2daed2ada6ab8bb6abc77a8 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 25 Feb 2021 20:20:03 +0100 Subject: [PATCH] JVM IR: prevent behavior change with operator dot calls on literals #KT-42321 Fixed --- ...irOldFrontendDiagnosticsTestGenerated.java | 6 + .../FirBlackBoxCodegenTestGenerated.java | 6 + .../runners/ir/Fir2IrTextTestGenerated.java | 6 + .../ir/backend/js/utils/OperatorNames.kt | 13 +- .../backend/jvm/JvmGeneratorExtensionsImpl.kt | 3 + .../psi2ir/generators/GeneratorExtensions.kt | 4 +- .../transformations/InsertImplicitCasts.kt | 54 +++- ...ngOfLiteralReceiverWithIntegerValueType.kt | 224 +++++++++++++++++ ...literalReceiverWithIntegerValueType.fir.kt | 67 +++++ .../literalReceiverWithIntegerValueType.kt | 67 +++++ .../literalReceiverWithIntegerValueType.txt | 16 ++ .../ir/irText/expressions/kt42321.fir.txt | 118 +++++++++ .../testData/ir/irText/expressions/kt42321.kt | 62 +++++ .../ir/irText/expressions/kt42321.txt | 233 ++++++++++++++++++ .../primitivesImplicitConversions.kt.txt | 16 +- .../primitivesImplicitConversions.txt | 40 ++- .../test/runners/DiagnosticTestGenerated.java | 6 + .../codegen/BlackBoxCodegenTestGenerated.java | 6 + .../IrBlackBoxCodegenTestGenerated.java | 6 + .../test/runners/ir/IrTextTestGenerated.java | 6 + .../LightAnalysisModeTestGenerated.java | 5 + .../kotlin/util/OperatorNameConventions.kt | 6 + 22 files changed, 920 insertions(+), 50 deletions(-) create mode 100644 compiler/testData/codegen/box/binaryOp/boxingOfLiteralReceiverWithIntegerValueType.kt create mode 100644 compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.fir.kt create mode 100644 compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt create mode 100644 compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.txt create mode 100644 compiler/testData/ir/irText/expressions/kt42321.fir.txt create mode 100644 compiler/testData/ir/irText/expressions/kt42321.kt create mode 100644 compiler/testData/ir/irText/expressions/kt42321.txt diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index ffdf635388e..a6dc5e17d78 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -18931,6 +18931,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/numbers/intValuesOutOfRange.kt"); } + @Test + @TestMetadata("literalReceiverWithIntegerValueType.kt") + public void testLiteralReceiverWithIntegerValueType() throws Exception { + runTest("compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt"); + } + @Test @TestMetadata("numberAsUnionAndIntersection.kt") public void testNumberAsUnionAndIntersection() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index c910662c044..c070cb51c3d 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -1334,6 +1334,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/binaryOp/bitwiseOpNullable.kt"); } + @Test + @TestMetadata("boxingOfLiteralReceiverWithIntegerValueType.kt") + public void testBoxingOfLiteralReceiverWithIntegerValueType() throws Exception { + runTest("compiler/testData/codegen/box/binaryOp/boxingOfLiteralReceiverWithIntegerValueType.kt"); + } + @Test @TestMetadata("call.kt") public void testCall() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java index 8e4989b1fd0..cdfa41d9541 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java @@ -1346,6 +1346,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/expressions/kt37779.kt"); } + @Test + @TestMetadata("kt42321.kt") + public void testKt42321() throws Exception { + runTest("compiler/testData/ir/irText/expressions/kt42321.kt"); + } + @Test @TestMetadata("kt45022.kt") public void testKt45022() throws Exception { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/OperatorNames.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/OperatorNames.kt index c6eddaf4b81..896dabb912d 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/OperatorNames.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/OperatorNames.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.ir.backend.js.utils -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.util.OperatorNameConventions object OperatorNames { @@ -21,12 +20,12 @@ object OperatorNames { val AND = OperatorNameConventions.AND val OR = OperatorNameConventions.OR - val XOR = Name.identifier("xor") - val INV = Name.identifier("inv") + val XOR = OperatorNameConventions.XOR + val INV = OperatorNameConventions.INV - val SHL = Name.identifier("shl") - val SHR = Name.identifier("shr") - val SHRU = Name.identifier("ushr") + val SHL = OperatorNameConventions.SHL + val SHR = OperatorNameConventions.SHR + val SHRU = OperatorNameConventions.USHR val NOT = OperatorNameConventions.NOT @@ -37,4 +36,4 @@ object OperatorNames { val BINARY = setOf(ADD, SUB, MUL, DIV, MOD, REM, AND, OR, XOR, SHL, SHR, SHRU) val UNARY = setOf(UNARY_PLUS, UNARY_MINUS, INV, NOT, INC, DEC) val ALL = BINARY + UNARY -} \ No newline at end of file +} diff --git a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt index e0855a2d60f..50df78604f4 100644 --- a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt +++ b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmGeneratorExtensionsImpl.kt @@ -160,6 +160,9 @@ class JvmGeneratorExtensionsImpl(private val generateFacades: Boolean = true) : ) } + override val shouldPreventDeprecatedIntegerValueTypeLiteralConversion: Boolean + get() = true + private val flexibleNullabilityAnnotationClass = createSpecialAnnotationClass(JvmSymbols.FLEXIBLE_NULLABILITY_ANNOTATION_FQ_NAME, kotlinIrInternalPackage) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt index 7e0b83e2c42..293dba5e463 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/GeneratorExtensions.kt @@ -20,7 +20,6 @@ open class GeneratorExtensions : StubGeneratorExtensions() { get() = SamConversion open class SamConversion { - open fun isPlatformSamType(type: KotlinType): Boolean = false open fun getSamTypeForValueParameter(valueParameter: ValueParameterDescriptor): KotlinType? = null @@ -37,4 +36,7 @@ open class GeneratorExtensions : StubGeneratorExtensions() { descriptor: ClassDescriptor, context: GeneratorContext, ): IrDelegatingConstructorCall? = null + + open val shouldPreventDeprecatedIntegerValueTypeLiteralConversion: Boolean + get() = false } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt index 601bbe06e6c..721487c5257 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InsertImplicitCasts.kt @@ -24,10 +24,8 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrField -import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.declarations.IrVariable +import org.jetbrains.kotlin.ir.PsiIrFileEntry +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrBasedDeclarationDescriptor import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.* @@ -35,33 +33,40 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol -import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.impl.originalKotlinType -import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.types.toKotlinType +import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.ir.util.TypeTranslator +import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi2ir.containsNull import org.jetbrains.kotlin.psi2ir.findSingleFunction import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions +import org.jetbrains.kotlin.psi2ir.generators.OPERATORS_DESUGARED_TO_CALLS import org.jetbrains.kotlin.psi2ir.generators.getSubstitutedFunctionTypeForSamType import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.typeUtil.* +import org.jetbrains.kotlin.util.OperatorNameConventions -fun insertImplicitCasts(element: IrElement, context: GeneratorContext) { +fun insertImplicitCasts(file: IrFile, context: GeneratorContext) { InsertImplicitCasts( context.builtIns, context.irBuiltIns, context.typeTranslator, context.callToSubstitutedDescriptorMap, context.extensions, - context.symbolTable - ).run(element) + context.symbolTable, + file, + ).run(file) } internal class InsertImplicitCasts( @@ -70,7 +75,8 @@ internal class InsertImplicitCasts( private val typeTranslator: TypeTranslator, private val callToSubstitutedDescriptorMap: Map, private val generatorExtensions: GeneratorExtensions, - private val symbolTable: SymbolTable + private val symbolTable: SymbolTable, + private val file: IrFile, ) : IrElementTransformerVoid() { private val expectedFunctionExpressionReturnType = hashMapOf() @@ -402,6 +408,11 @@ internal class InsertImplicitCasts( private fun IrExpression.coerceIntToAnotherIntegerType(targetType: KotlinType): IrExpression { if (!type.originalKotlinType!!.isInt()) throw AssertionError("Expression of type 'kotlin.Int' expected: $this") if (targetType.isInt()) return this + + if (generatorExtensions.shouldPreventDeprecatedIntegerValueTypeLiteralConversion && + this is IrCall && preventDeprecatedIntegerValueTypeLiteralConversion() + ) return this + return if (this is IrConst<*>) { val value = this.value as Int val irType = targetType.toIrType() @@ -429,6 +440,29 @@ internal class InsertImplicitCasts( } } + // In JVM, we don't convert values resulted from calling built-in operators on integer literals to another integer type. + // The reason is that doing so would change behavior, which we want to avoid, see KT-42321. + // At the same time, such structure seems possible to achieve only via the magical integer value type, but inferring the result of + // the operator call based on an expected type is deprecated behavior which is going to be removed in the future, see KT-38895. + private fun IrCall.preventDeprecatedIntegerValueTypeLiteralConversion(): Boolean { + val descriptor = symbol.descriptor + if (descriptor.name !in operatorsWithDeprecatedIntegerValueTypeLiteralConversion) return false + + // This bug is only reproducible for non-operator calls, for example "1.plus(2)", NOT "1 + 2". + if (origin in OPERATORS_DESUGARED_TO_CALLS) return false + + // For infix methods, this bug is only reproducible for non-infix calls, for example "1.shl(2)", NOT "1 shl 2". + if (descriptor.isInfix) { + if ((file.fileEntry as? PsiIrFileEntry)?.findPsiElement(this) is KtBinaryExpression) return false + } + + return descriptor.dispatchReceiverParameter?.type?.let { KotlinBuiltIns.isPrimitiveType(it) } == true + } + + private val operatorsWithDeprecatedIntegerValueTypeLiteralConversion = with(OperatorNameConventions) { + setOf(PLUS, MINUS, TIMES, DIV, REM, UNARY_PLUS, UNARY_MINUS, SHL, SHR, USHR, AND, OR, XOR, INV) + } + private fun IrExpression.invokeIntegerCoercionFunction(targetType: KotlinType, coercionFunName: String): IrExpression { val coercionFunction = builtIns.int.unsubstitutedMemberScope.findSingleFunction(Name.identifier(coercionFunName)) return IrCallImpl( diff --git a/compiler/testData/codegen/box/binaryOp/boxingOfLiteralReceiverWithIntegerValueType.kt b/compiler/testData/codegen/box/binaryOp/boxingOfLiteralReceiverWithIntegerValueType.kt new file mode 100644 index 00000000000..2c5917d5e69 --- /dev/null +++ b/compiler/testData/codegen/box/binaryOp/boxingOfLiteralReceiverWithIntegerValueType.kt @@ -0,0 +1,224 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR +// WITH_RUNTIME +// This test exists only to check that we don't accidentally break the buggy behavior of the old JVM backend in JVM IR (KT-42321). +// Feel free to remove it as soon as there's no language version where such code is allowed (KT-38895). + +// FILE: test.kt + +import kotlin.reflect.KClass + +class K(val type: KClass) { + fun check(o: L, description: String, expected: KClass = Int::class) { + val x = o as Any + if (x::class != expected) { + throw AssertionError("Fail K<${type.simpleName}> $description: " + + "expected ${expected.qualifiedName}, actual ${x::class.qualifiedName}") + } + } +} + +fun box(): String { + val kl = K(Long::class) + kl.check(1.plus(2), "plus", Int::class) + kl.check(1.minus(2), "minus", Int::class) + kl.check(1.times(2), "times", Int::class) + kl.check(1.div(2), "div", Int::class) + kl.check(1.rem(2), "rem", Int::class) + kl.check(1.unaryPlus(), "unaryPlus", Int::class) + kl.check(1.unaryMinus(), "unaryMinus", Int::class) + kl.check(1.shl(2), "shl", Int::class) + kl.check(1.shr(2), "shr", Int::class) + kl.check(1.ushr(2), "ushr", Int::class) + kl.check(1.and(2), "and", Int::class) + kl.check(1.or(2), "or", Int::class) + kl.check(1.xor(2), "xor", Int::class) + kl.check(1.inv(), "inv", Int::class) + + kl.check(1 + 2, "plus via operator", Long::class) + kl.check(1 - 2, "minus via operator", Long::class) + kl.check(1 * 2, "times via operator", Long::class) + kl.check(1 / 2, "div via operator", Long::class) + kl.check(1 % 2, "rem via operator", Long::class) + kl.check(+1, "unaryPlus via operator", Long::class) + kl.check(-1, "unaryMinus via operator", Long::class) + kl.check(1 shl 2, "shl infix", Long::class) + kl.check(1 shr 2, "shr infix", Long::class) + kl.check(1 ushr 2, "ushr infix", Long::class) + kl.check(1 and 2, "and infix", Long::class) + kl.check(1 or 2, "or infix", Long::class) + kl.check(1 xor 2, "xor infix", Long::class) + + val ks = K(Short::class) + ks.check(1.plus(2), "plus", Int::class) + ks.check(1.minus(2), "minus", Int::class) + ks.check(1.times(2), "times", Int::class) + ks.check(1.div(2), "div", Int::class) + ks.check(1.rem(2), "rem", Int::class) + ks.check(1.unaryPlus(), "unaryPlus", Int::class) + ks.check(1.unaryMinus(), "unaryMinus", Int::class) + ks.check(1.shl(2), "shl", Int::class) + ks.check(1.shr(2), "shr", Int::class) + ks.check(1.ushr(2), "ushr", Int::class) + ks.check(1.and(2), "and", Int::class) + ks.check(1.or(2), "or", Int::class) + ks.check(1.xor(2), "xor", Int::class) + ks.check(1.inv(), "inv", Int::class) + + ks.check(1 + 2, "plus via operator", Short::class) + ks.check(1 - 2, "minus via operator", Short::class) + ks.check(1 * 2, "times via operator", Short::class) + ks.check(1 / 2, "div via operator", Short::class) + ks.check(1 % 2, "rem via operator", Short::class) + ks.check(+1, "unaryPlus via operator", Short::class) + ks.check(-1, "unaryMinus via operator", Short::class) + ks.check(1 shl 2, "shl infix", Short::class) + ks.check(1 shr 2, "shr infix", Short::class) + ks.check(1 ushr 2, "ushr infix", Short::class) + ks.check(1 and 2, "and infix", Short::class) + ks.check(1 or 2, "or infix", Short::class) + ks.check(1 xor 2, "xor infix", Short::class) + + val kb = K(Byte::class) + kb.check(1.plus(2), "plus", Int::class) + kb.check(1.minus(2), "minus", Int::class) + kb.check(1.times(2), "times", Int::class) + kb.check(1.div(2), "div", Int::class) + kb.check(1.rem(2), "rem", Int::class) + kb.check(1.unaryPlus(), "unaryPlus", Int::class) + kb.check(1.unaryMinus(), "unaryMinus", Int::class) + kb.check(1.shl(2), "shl", Int::class) + kb.check(1.shr(2), "shr", Int::class) + kb.check(1.ushr(2), "ushr", Int::class) + kb.check(1.and(2), "and", Int::class) + kb.check(1.or(2), "or", Int::class) + kb.check(1.xor(2), "xor", Int::class) + kb.check(1.inv(), "inv", Int::class) + + kb.check(1 + 2, "plus via operator", Byte::class) + kb.check(1 - 2, "minus via operator", Byte::class) + kb.check(1 * 2, "times via operator", Byte::class) + kb.check(1 / 2, "div via operator", Byte::class) + kb.check(1 % 2, "rem via operator", Byte::class) + kb.check(+1, "unaryPlus via operator", Byte::class) + kb.check(-1, "unaryMinus via operator", Byte::class) + kb.check(1 shl 2, "shl infix", Byte::class) + kb.check(1 shr 2, "shr infix", Byte::class) + kb.check(1 ushr 2, "ushr infix", Byte::class) + kb.check(1 and 2, "and infix", Byte::class) + kb.check(1 or 2, "or infix", Byte::class) + kb.check(1 xor 2, "xor infix", Byte::class) + + val jl = J(Long::class) + jl.check(1.plus(2), "plus", Int::class) + jl.check(1.minus(2), "minus", Int::class) + jl.check(1.times(2), "times", Int::class) + jl.check(1.div(2), "div", Int::class) + jl.check(1.rem(2), "rem", Int::class) + jl.check(1.unaryPlus(), "unaryPlus", Int::class) + jl.check(1.unaryMinus(), "unaryMinus", Int::class) + jl.check(1.shl(2), "shl", Int::class) + jl.check(1.shr(2), "shr", Int::class) + jl.check(1.ushr(2), "ushr", Int::class) + jl.check(1.and(2), "and", Int::class) + jl.check(1.or(2), "or", Int::class) + jl.check(1.xor(2), "xor", Int::class) + jl.check(1.inv(), "inv", Int::class) + + jl.check(1 + 2, "plus via operator", Long::class) + jl.check(1 - 2, "minus via operator", Long::class) + jl.check(1 * 2, "times via operator", Long::class) + jl.check(1 / 2, "div via operator", Long::class) + jl.check(1 % 2, "rem via operator", Long::class) + jl.check(+1, "unaryPlus via operator", Long::class) + jl.check(-1, "unaryMinus via operator", Long::class) + jl.check(1 shl 2, "shl infix", Long::class) + jl.check(1 shr 2, "shr infix", Long::class) + jl.check(1 ushr 2, "ushr infix", Long::class) + jl.check(1 and 2, "and infix", Long::class) + jl.check(1 or 2, "or infix", Long::class) + jl.check(1 xor 2, "xor infix", Long::class) + + val js = J(Short::class) + js.check(1.plus(2), "plus", Int::class) + js.check(1.minus(2), "minus", Int::class) + js.check(1.times(2), "times", Int::class) + js.check(1.div(2), "div", Int::class) + js.check(1.rem(2), "rem", Int::class) + js.check(1.unaryPlus(), "unaryPlus", Int::class) + js.check(1.unaryMinus(), "unaryMinus", Int::class) + js.check(1.shl(2), "shl", Int::class) + js.check(1.shr(2), "shr", Int::class) + js.check(1.ushr(2), "ushr", Int::class) + js.check(1.and(2), "and", Int::class) + js.check(1.or(2), "or", Int::class) + js.check(1.xor(2), "xor", Int::class) + js.check(1.inv(), "inv", Int::class) + + js.check(1 + 2, "plus via operator", Short::class) + js.check(1 - 2, "minus via operator", Short::class) + js.check(1 * 2, "times via operator", Short::class) + js.check(1 / 2, "div via operator", Short::class) + js.check(1 % 2, "rem via operator", Short::class) + js.check(+1, "unaryPlus via operator", Short::class) + js.check(-1, "unaryMinus via operator", Short::class) + js.check(1 shl 2, "shl infix", Short::class) + js.check(1 shr 2, "shr infix", Short::class) + js.check(1 ushr 2, "ushr infix", Short::class) + js.check(1 and 2, "and infix", Short::class) + js.check(1 or 2, "or infix", Short::class) + js.check(1 xor 2, "xor infix", Short::class) + + val jb = J(Byte::class) + jb.check(1.plus(2), "plus", Int::class) + jb.check(1.minus(2), "minus", Int::class) + jb.check(1.times(2), "times", Int::class) + jb.check(1.div(2), "div", Int::class) + jb.check(1.rem(2), "rem", Int::class) + jb.check(1.unaryPlus(), "unaryPlus", Int::class) + jb.check(1.unaryMinus(), "unaryMinus", Int::class) + jb.check(1.shl(2), "shl", Int::class) + jb.check(1.shr(2), "shr", Int::class) + jb.check(1.ushr(2), "ushr", Int::class) + jb.check(1.and(2), "and", Int::class) + jb.check(1.or(2), "or", Int::class) + jb.check(1.xor(2), "xor", Int::class) + jb.check(1.inv(), "inv", Int::class) + + jb.check(1 + 2, "plus via operator", Byte::class) + jb.check(1 - 2, "minus via operator", Byte::class) + jb.check(1 * 2, "times via operator", Byte::class) + jb.check(1 / 2, "div via operator", Byte::class) + jb.check(1 % 2, "rem via operator", Byte::class) + jb.check(+1, "unaryPlus via operator", Byte::class) + jb.check(-1, "unaryMinus via operator", Byte::class) + jb.check(1 shl 2, "shl infix", Byte::class) + jb.check(1 shr 2, "shr infix", Byte::class) + jb.check(1 ushr 2, "ushr infix", Byte::class) + jb.check(1 and 2, "and infix", Byte::class) + jb.check(1 or 2, "or infix", Byte::class) + jb.check(1 xor 2, "xor infix", Byte::class) + + return "OK" +} + +// FILE: J.java + +import kotlin.jvm.JvmClassMappingKt; +import kotlin.reflect.KClass; + +public class J { + private final KClass type; + + public J(KClass type) { + this.type = type; + } + + public void check(M x, String description, KClass expected) { + KClass actual = JvmClassMappingKt.getKotlinClass(x.getClass()); + if (!actual.equals(expected)) { + throw new AssertionError("Fail J<" + type.getSimpleName() + "> " + description + ": " + + "expected: " + expected.getQualifiedName() + ", actual: " + actual.getQualifiedName()); + } + } +} diff --git a/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.fir.kt b/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.fir.kt new file mode 100644 index 00000000000..c215250faf9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.fir.kt @@ -0,0 +1,67 @@ +// This test exists only to check that we don't accidentally break the buggy behavior of the old JVM backend in JVM IR (KT-42321). +// Feel free to remove it as soon as there's no language version where such code is allowed (KT-38895). + +abstract class C { + abstract fun takeT(x: L) +} + +fun testLongDotCall(c1: C) { + c1.takeT(1.plus(2)) + c1.takeT(1.minus(2)) + c1.takeT(1.times(2)) + c1.takeT(1.div(2)) + c1.takeT(1.rem(2)) + c1.takeT(1.inc()) + c1.takeT(1.dec()) + c1.takeT(1.unaryPlus()) + c1.takeT(1.unaryMinus()) + c1.takeT(1.shl(2)) + c1.takeT(1.shr(2)) + c1.takeT(1.ushr(2)) + c1.takeT(1.and(2)) + c1.takeT(1.or(2)) + c1.takeT(1.xor(2)) + c1.takeT(1.inv()) +} + +fun testShortDotCall(c2: C) { + c2.takeT(1.plus(2)) + c2.takeT(1.inc()) + c2.takeT(1.dec()) + c2.takeT(1.shr(2)) + c2.takeT(1.inv()) +} + +fun testByteDotCall(c3: C) { + c3.takeT(1.plus(2)) + c3.takeT(1.inc()) + c3.takeT(1.dec()) + c3.takeT(1.shr(2)) + c3.takeT(1.inv()) +} + +fun testLongOperatorInfixCall(c4: C) { + c4.takeT(1 + 2) + c4.takeT(1 - 2) + c4.takeT(1 * 2) + c4.takeT(1 / 2) + c4.takeT(1 % 2) + c4.takeT(+1) + c4.takeT(-1) + c4.takeT(1 shl 2) + c4.takeT(1 shr 2) + c4.takeT(1 ushr 2) + c4.takeT(1 and 2) + c4.takeT(1 or 2) + c4.takeT(1 xor 2) +} + +fun testShortOperatorInfixCall(c5: C) { + c5.takeT(1 + 2) + c5.takeT(1 shr 2) +} + +fun testByteOperatorInfixCall(c6: C) { + c6.takeT(1 + 2) + c6.takeT(1 shr 2) +} diff --git a/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt b/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt new file mode 100644 index 00000000000..498a7380b01 --- /dev/null +++ b/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt @@ -0,0 +1,67 @@ +// This test exists only to check that we don't accidentally break the buggy behavior of the old JVM backend in JVM IR (KT-42321). +// Feel free to remove it as soon as there's no language version where such code is allowed (KT-38895). + +abstract class C { + abstract fun takeT(x: L) +} + +fun testLongDotCall(c1: C) { + c1.takeT(1.plus(2)) + c1.takeT(1.minus(2)) + c1.takeT(1.times(2)) + c1.takeT(1.div(2)) + c1.takeT(1.rem(2)) + c1.takeT(1.inc()) + c1.takeT(1.dec()) + c1.takeT(1.unaryPlus()) + c1.takeT(1.unaryMinus()) + c1.takeT(1.shl(2)) + c1.takeT(1.shr(2)) + c1.takeT(1.ushr(2)) + c1.takeT(1.and(2)) + c1.takeT(1.or(2)) + c1.takeT(1.xor(2)) + c1.takeT(1.inv()) +} + +fun testShortDotCall(c2: C) { + c2.takeT(1.plus(2)) + c2.takeT(1.inc()) + c2.takeT(1.dec()) + c2.takeT(1.shr(2)) + c2.takeT(1.inv()) +} + +fun testByteDotCall(c3: C) { + c3.takeT(1.plus(2)) + c3.takeT(1.inc()) + c3.takeT(1.dec()) + c3.takeT(1.shr(2)) + c3.takeT(1.inv()) +} + +fun testLongOperatorInfixCall(c4: C) { + c4.takeT(1 + 2) + c4.takeT(1 - 2) + c4.takeT(1 * 2) + c4.takeT(1 / 2) + c4.takeT(1 % 2) + c4.takeT(+1) + c4.takeT(-1) + c4.takeT(1 shl 2) + c4.takeT(1 shr 2) + c4.takeT(1 ushr 2) + c4.takeT(1 and 2) + c4.takeT(1 or 2) + c4.takeT(1 xor 2) +} + +fun testShortOperatorInfixCall(c5: C) { + c5.takeT(1 + 2) + c5.takeT(1 shr 2) +} + +fun testByteOperatorInfixCall(c6: C) { + c6.takeT(1 + 2) + c6.takeT(1 shr 2) +} diff --git a/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.txt b/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.txt new file mode 100644 index 00000000000..afff93d1954 --- /dev/null +++ b/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.txt @@ -0,0 +1,16 @@ +package + +public fun testByteDotCall(/*0*/ c3: C): kotlin.Unit +public fun testByteOperatorInfixCall(/*0*/ c6: C): kotlin.Unit +public fun testLongDotCall(/*0*/ c1: C): kotlin.Unit +public fun testLongOperatorInfixCall(/*0*/ c4: C): kotlin.Unit +public fun testShortDotCall(/*0*/ c2: C): kotlin.Unit +public fun testShortOperatorInfixCall(/*0*/ c5: C): kotlin.Unit + +public abstract class C { + public constructor C() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public abstract fun takeT(/*0*/ x: L): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/ir/irText/expressions/kt42321.fir.txt b/compiler/testData/ir/irText/expressions/kt42321.fir.txt new file mode 100644 index 00000000000..3c6a100a8ea --- /dev/null +++ b/compiler/testData/ir/irText/expressions/kt42321.fir.txt @@ -0,0 +1,118 @@ +FILE fqName: fileName:/kt42321.kt + CLASS CLASS name:C modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C.C> + TYPE_PARAMETER name:L index:0 variance: superTypes:[kotlin.Any?] + CONSTRUCTOR visibility:public <> () returnType:.C.C> [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' + FUN name:takeT visibility:public modality:ABSTRACT <> ($this:.C.C>, x:L of .C) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.C.C> + VALUE_PARAMETER name:x index:0 type:L of .C + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN name:testLongDotCall visibility:public modality:FINAL <> (c1:.C) returnType:kotlin.Unit + VALUE_PARAMETER name:c1 index:0 type:.C + BLOCK_BODY + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=3 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=-1 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=2 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=0 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=1 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=1 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=-1 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=4 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=0 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=0 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=0 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=3 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=3 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=-2 + FUN name:testShortDotCall visibility:public modality:FINAL <> (c2:.C) returnType:kotlin.Unit + VALUE_PARAMETER name:c2 index:0 type:.C + BLOCK_BODY + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=3 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=0 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=-2 + FUN name:testByteDotCall visibility:public modality:FINAL <> (c3:.C) returnType:kotlin.Unit + VALUE_PARAMETER name:c3 index:0 type:.C + BLOCK_BODY + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=3 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=0 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=-2 + FUN name:testLongOperatorInfixCall visibility:public modality:FINAL <> (c4:.C) returnType:kotlin.Unit + VALUE_PARAMETER name:c4 index:0 type:.C + BLOCK_BODY + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=3 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=-1 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=2 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=0 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=1 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CONST Long type=kotlin.Long value=1 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CONST Long type=kotlin.Long value=-1 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=4 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=0 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=0 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=0 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=3 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=3 + FUN name:testShortOperatorInfixCall visibility:public modality:FINAL <> (c5:.C) returnType:kotlin.Unit + VALUE_PARAMETER name:c5 index:0 type:.C + BLOCK_BODY + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=3 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=0 + FUN name:testByteOperatorInfixCall visibility:public modality:FINAL <> (c6:.C) returnType:kotlin.Unit + VALUE_PARAMETER name:c6 index:0 type:.C + BLOCK_BODY + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=3 + ERROR_CALL 'Unresolved reference: #' type=kotlin.Unit + CONST Int type=kotlin.Int value=0 diff --git a/compiler/testData/ir/irText/expressions/kt42321.kt b/compiler/testData/ir/irText/expressions/kt42321.kt new file mode 100644 index 00000000000..fadc2b2d4b4 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/kt42321.kt @@ -0,0 +1,62 @@ +// SKIP_KT_DUMP +// This test exists only to check that we don't accidentally break the buggy behavior of the old JVM backend in JVM IR (KT-42321). +// Feel free to remove it as soon as there's no language version where such code is allowed (KT-38895). + +abstract class C { + abstract fun takeT(x: L) +} + +fun testLongDotCall(c1: C) { + c1.takeT(1.plus(2)) + c1.takeT(1.minus(2)) + c1.takeT(1.times(2)) + c1.takeT(1.div(2)) + c1.takeT(1.rem(2)) + c1.takeT(1.unaryPlus()) + c1.takeT(1.unaryMinus()) + c1.takeT(1.shl(2)) + c1.takeT(1.shr(2)) + c1.takeT(1.ushr(2)) + c1.takeT(1.and(2)) + c1.takeT(1.or(2)) + c1.takeT(1.xor(2)) + c1.takeT(1.inv()) +} + +fun testShortDotCall(c2: C) { + c2.takeT(1.plus(2)) + c2.takeT(1.shr(2)) + c2.takeT(1.inv()) +} + +fun testByteDotCall(c3: C) { + c3.takeT(1.plus(2)) + c3.takeT(1.shr(2)) + c3.takeT(1.inv()) +} + +fun testLongOperatorInfixCall(c4: C) { + c4.takeT(1 + 2) + c4.takeT(1 - 2) + c4.takeT(1 * 2) + c4.takeT(1 / 2) + c4.takeT(1 % 2) + c4.takeT(+1) + c4.takeT(-1) + c4.takeT(1 shl 2) + c4.takeT(1 shr 2) + c4.takeT(1 ushr 2) + c4.takeT(1 and 2) + c4.takeT(1 or 2) + c4.takeT(1 xor 2) +} + +fun testShortOperatorInfixCall(c5: C) { + c5.takeT(1 + 2) + c5.takeT(1 shr 2) +} + +fun testByteOperatorInfixCall(c6: C) { + c6.takeT(1 + 2) + c6.takeT(1 shr 2) +} diff --git a/compiler/testData/ir/irText/expressions/kt42321.txt b/compiler/testData/ir/irText/expressions/kt42321.txt new file mode 100644 index 00000000000..7e5c8f453fa --- /dev/null +++ b/compiler/testData/ir/irText/expressions/kt42321.txt @@ -0,0 +1,233 @@ +FILE fqName: fileName:/kt42321.kt + CLASS CLASS name:C modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C.C> + TYPE_PARAMETER name:L index:0 variance: superTypes:[kotlin.Any?] + CONSTRUCTOR visibility:public <> () returnType:.C.C> [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' + FUN name:takeT visibility:public modality:ABSTRACT <> ($this:.C.C>, x:L of .C) returnType:kotlin.Unit + $this: VALUE_PARAMETER name: type:.C.C> + VALUE_PARAMETER name:x index:0 type:L of .C + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN name:testLongDotCall visibility:public modality:FINAL <> (c1:.C) returnType:kotlin.Unit + VALUE_PARAMETER name:c1 index:0 type:.C + BLOCK_BODY + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun minus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun times (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun div (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun rem (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun unaryPlus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun shl (bitCount: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + bitCount: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun shr (bitCount: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + bitCount: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun ushr (bitCount: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + bitCount: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun and (other: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun or (other: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun xor (other: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c1: .C declared in .testLongDotCall' type=.C origin=null + x: CALL 'public final fun inv (): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + FUN name:testShortDotCall visibility:public modality:FINAL <> (c2:.C) returnType:kotlin.Unit + VALUE_PARAMETER name:c2 index:0 type:.C + BLOCK_BODY + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c2: .C declared in .testShortDotCall' type=.C origin=null + x: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c2: .C declared in .testShortDotCall' type=.C origin=null + x: CALL 'public final fun shr (bitCount: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + bitCount: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c2: .C declared in .testShortDotCall' type=.C origin=null + x: CALL 'public final fun inv (): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + FUN name:testByteDotCall visibility:public modality:FINAL <> (c3:.C) returnType:kotlin.Unit + VALUE_PARAMETER name:c3 index:0 type:.C + BLOCK_BODY + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c3: .C declared in .testByteDotCall' type=.C origin=null + x: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c3: .C declared in .testByteDotCall' type=.C origin=null + x: CALL 'public final fun shr (bitCount: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + bitCount: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c3: .C declared in .testByteDotCall' type=.C origin=null + x: CALL 'public final fun inv (): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + FUN name:testLongOperatorInfixCall visibility:public modality:FINAL <> (c4:.C) returnType:kotlin.Unit + VALUE_PARAMETER name:c4 index:0 type:.C + BLOCK_BODY + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null + $this: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PLUS + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null + $this: CALL 'public final fun minus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=MINUS + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null + $this: CALL 'public final fun times (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=MUL + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null + $this: CALL 'public final fun div (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=DIV + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null + $this: CALL 'public final fun rem (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PERC + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CONST Long type=kotlin.Long value=1 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CONST Long type=kotlin.Long value=-1 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null + $this: CALL 'public final fun shl (bitCount: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + bitCount: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null + $this: CALL 'public final fun shr (bitCount: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + bitCount: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null + $this: CALL 'public final fun ushr (bitCount: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + bitCount: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null + $this: CALL 'public final fun and (other: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null + $this: CALL 'public final fun or (other: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c4: .C declared in .testLongOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null + $this: CALL 'public final fun xor (other: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + FUN name:testShortOperatorInfixCall visibility:public modality:FINAL <> (c5:.C) returnType:kotlin.Unit + VALUE_PARAMETER name:c5 index:0 type:.C + BLOCK_BODY + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c5: .C declared in .testShortOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toShort (): kotlin.Short declared in kotlin.Int' type=kotlin.Short origin=null + $this: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PLUS + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c5: .C declared in .testShortOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toShort (): kotlin.Short declared in kotlin.Int' type=kotlin.Short origin=null + $this: CALL 'public final fun shr (bitCount: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + bitCount: CONST Int type=kotlin.Int value=2 + FUN name:testByteOperatorInfixCall visibility:public modality:FINAL <> (c6:.C) returnType:kotlin.Unit + VALUE_PARAMETER name:c6 index:0 type:.C + BLOCK_BODY + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c6: .C declared in .testByteOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toByte (): kotlin.Byte declared in kotlin.Int' type=kotlin.Byte origin=null + $this: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=PLUS + $this: CONST Int type=kotlin.Int value=1 + other: CONST Int type=kotlin.Int value=2 + CALL 'public abstract fun takeT (x: L of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=null + $this: GET_VAR 'c6: .C declared in .testByteOperatorInfixCall' type=.C origin=null + x: CALL 'public open fun toByte (): kotlin.Byte declared in kotlin.Int' type=kotlin.Byte origin=null + $this: CALL 'public final fun shr (bitCount: kotlin.Int): kotlin.Int [infix] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 + bitCount: CONST Int type=kotlin.Int value=2 diff --git a/compiler/testData/ir/irText/expressions/primitivesImplicitConversions.kt.txt b/compiler/testData/ir/irText/expressions/primitivesImplicitConversions.kt.txt index 529d112c01d..b837b055c64 100644 --- a/compiler/testData/ir/irText/expressions/primitivesImplicitConversions.kt.txt +++ b/compiler/testData/ir/irText/expressions/primitivesImplicitConversions.kt.txt @@ -11,15 +11,15 @@ val test3: Byte get val test4: Long - field = 42.unaryMinus().toLong() + field = 42.unaryMinus() get val test5: Short - field = 42.unaryMinus().toShort() + field = 42.unaryMinus() get val test6: Byte - field = 42.unaryMinus().toByte() + field = 42.unaryMinus() get fun test() { @@ -27,16 +27,16 @@ fun test() { val test2: Long = 42L val test3: Long? = 42L val test4: Long? = -1L - val test5: Long? = 1.unaryMinus().toLong() - val test6: Short? = 1.unaryMinus().toShort() - val test7: Byte? = 1.unaryMinus().toByte() + val test5: Long? = 1.unaryMinus() + val test6: Short? = 1.unaryMinus() + val test7: Byte? = 1.unaryMinus() } -fun testImplicitArguments(x: Long = 1.unaryMinus().toLong()) { +fun testImplicitArguments(x: Long = 1.unaryMinus()) { } class TestImplicitArguments { - constructor(x: Long = 1.unaryMinus().toLong()) /* primary */ { + constructor(x: Long = 1.unaryMinus()) /* primary */ { super/*Any*/() /* () */ diff --git a/compiler/testData/ir/irText/expressions/primitivesImplicitConversions.txt b/compiler/testData/ir/irText/expressions/primitivesImplicitConversions.txt index 1ad672cde02..6ad8eda1e07 100644 --- a/compiler/testData/ir/irText/expressions/primitivesImplicitConversions.txt +++ b/compiler/testData/ir/irText/expressions/primitivesImplicitConversions.txt @@ -29,9 +29,8 @@ FILE fqName: fileName:/primitivesImplicitConversions.kt PROPERTY name:test4 visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test4 type:kotlin.Long visibility:private [final,static] EXPRESSION_BODY - CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null - $this: CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: CONST Int type=kotlin.Int value=42 + CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=42 FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Long correspondingProperty: PROPERTY name:test4 visibility:public modality:FINAL [val] BLOCK_BODY @@ -40,9 +39,8 @@ FILE fqName: fileName:/primitivesImplicitConversions.kt PROPERTY name:test5 visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test5 type:kotlin.Short visibility:private [final,static] EXPRESSION_BODY - CALL 'public open fun toShort (): kotlin.Short declared in kotlin.Int' type=kotlin.Short origin=null - $this: CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: CONST Int type=kotlin.Int value=42 + CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=42 FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Short correspondingProperty: PROPERTY name:test5 visibility:public modality:FINAL [val] BLOCK_BODY @@ -51,9 +49,8 @@ FILE fqName: fileName:/primitivesImplicitConversions.kt PROPERTY name:test6 visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test6 type:kotlin.Byte visibility:private [final,static] EXPRESSION_BODY - CALL 'public open fun toByte (): kotlin.Byte declared in kotlin.Int' type=kotlin.Byte origin=null - $this: CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: CONST Int type=kotlin.Int value=42 + CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=42 FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.Byte correspondingProperty: PROPERTY name:test6 visibility:public modality:FINAL [val] BLOCK_BODY @@ -70,32 +67,27 @@ FILE fqName: fileName:/primitivesImplicitConversions.kt VAR name:test4 type:kotlin.Long? [val] CONST Long type=kotlin.Long value=-1 VAR name:test5 type:kotlin.Long? [val] - CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null - $this: CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: CONST Int type=kotlin.Int value=1 + CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 VAR name:test6 type:kotlin.Short? [val] - CALL 'public open fun toShort (): kotlin.Short declared in kotlin.Int' type=kotlin.Short origin=null - $this: CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: CONST Int type=kotlin.Int value=1 + CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 VAR name:test7 type:kotlin.Byte? [val] - CALL 'public open fun toByte (): kotlin.Byte declared in kotlin.Int' type=kotlin.Byte origin=null - $this: CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: CONST Int type=kotlin.Int value=1 + CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 FUN name:testImplicitArguments visibility:public modality:FINAL <> (x:kotlin.Long) returnType:kotlin.Unit VALUE_PARAMETER name:x index:0 type:kotlin.Long EXPRESSION_BODY - CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null - $this: CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: CONST Int type=kotlin.Int value=1 + CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 BLOCK_BODY CLASS CLASS name:TestImplicitArguments modality:FINAL visibility:public superTypes:[kotlin.Any] $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.TestImplicitArguments CONSTRUCTOR visibility:public <> (x:kotlin.Long) returnType:.TestImplicitArguments [primary] VALUE_PARAMETER name:x index:0 type:kotlin.Long EXPRESSION_BODY - CALL 'public open fun toLong (): kotlin.Long declared in kotlin.Int' type=kotlin.Long origin=null - $this: CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null - $this: CONST Int type=kotlin.Int value=1 + CALL 'public final fun unaryMinus (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null + $this: CONST Int type=kotlin.Int value=1 BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:TestImplicitArguments modality:FINAL visibility:public superTypes:[kotlin.Any]' diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 024521410d2..8fea46e8a27 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -18937,6 +18937,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/numbers/intValuesOutOfRange.kt"); } + @Test + @TestMetadata("literalReceiverWithIntegerValueType.kt") + public void testLiteralReceiverWithIntegerValueType() throws Exception { + runTest("compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt"); + } + @Test @TestMetadata("numberAsUnionAndIntersection.kt") public void testNumberAsUnionAndIntersection() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 125d2062fcb..686883c69bf 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -1334,6 +1334,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/binaryOp/bitwiseOpNullable.kt"); } + @Test + @TestMetadata("boxingOfLiteralReceiverWithIntegerValueType.kt") + public void testBoxingOfLiteralReceiverWithIntegerValueType() throws Exception { + runTest("compiler/testData/codegen/box/binaryOp/boxingOfLiteralReceiverWithIntegerValueType.kt"); + } + @Test @TestMetadata("call.kt") public void testCall() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 57b232fe3e5..f10817d1740 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -1334,6 +1334,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/binaryOp/bitwiseOpNullable.kt"); } + @Test + @TestMetadata("boxingOfLiteralReceiverWithIntegerValueType.kt") + public void testBoxingOfLiteralReceiverWithIntegerValueType() throws Exception { + runTest("compiler/testData/codegen/box/binaryOp/boxingOfLiteralReceiverWithIntegerValueType.kt"); + } + @Test @TestMetadata("call.kt") public void testCall() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java index a1a4dc7681f..f412f8e76bb 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java @@ -1346,6 +1346,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest { runTest("compiler/testData/ir/irText/expressions/kt37779.kt"); } + @Test + @TestMetadata("kt42321.kt") + public void testKt42321() throws Exception { + runTest("compiler/testData/ir/irText/expressions/kt42321.kt"); + } + @Test @TestMetadata("kt45022.kt") public void testKt45022() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 730c9aca0f2..efc2204c4f3 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -1186,6 +1186,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/binaryOp/bitwiseOpNullable.kt"); } + @TestMetadata("boxingOfLiteralReceiverWithIntegerValueType.kt") + public void testBoxingOfLiteralReceiverWithIntegerValueType() throws Exception { + runTest("compiler/testData/codegen/box/binaryOp/boxingOfLiteralReceiverWithIntegerValueType.kt"); + } + @TestMetadata("call.kt") public void testCall() throws Exception { runTest("compiler/testData/codegen/box/binaryOp/call.kt"); diff --git a/core/compiler.common/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt b/core/compiler.common/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt index 48accef1627..ae4495e2187 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/util/OperatorNameConventions.kt @@ -39,6 +39,12 @@ object OperatorNameConventions { @JvmField val AND = Name.identifier("and") @JvmField val OR = Name.identifier("or") + @JvmField val XOR = Name.identifier("xor") + @JvmField val INV = Name.identifier("inv") + + @JvmField val SHL = Name.identifier("shl") + @JvmField val SHR = Name.identifier("shr") + @JvmField val USHR = Name.identifier("ushr") @JvmField val INC = Name.identifier("inc") @JvmField val DEC = Name.identifier("dec")