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 125ff5ec65d..c83afcd3996 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 @@ -19087,6 +19087,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt"); } + @Test + @TestMetadata("newLiteralOperatorsResolution_warning.kt") + public void testNewLiteralOperatorsResolution_warning() throws Exception { + runTest("compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_warning.kt"); + } + @Test @TestMetadata("numberAsUnionAndIntersection.kt") public void testNumberAsUnionAndIntersection() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index aee06fa7107..6bad1c467f3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -1017,6 +1017,7 @@ public interface Errors { DiagnosticFactory0 ILLEGAL_ESCAPE_SEQUENCE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 UNSIGNED_LITERAL_WITHOUT_DECLARATIONS_ON_CLASSPATH = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED = DiagnosticFactory0.create(ERROR); + DiagnosticFactory1 INTEGER_OPERATOR_RESOLVE_WILL_CHANGE = DiagnosticFactory1.create(WARNING); // Casts and is-checks diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index bb87ce2a511..06e6a9bdc7a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -435,6 +435,7 @@ public class DefaultErrorMessages { MAP.put(ILLEGAL_ESCAPE_SEQUENCE, "Illegal escape sequence"); MAP.put(UNSIGNED_LITERAL_WITHOUT_DECLARATIONS_ON_CLASSPATH, "Type of the constant expression cannot be resolved. Please make sure you have the required dependencies for unsigned types in the classpath"); MAP.put(SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED, "Conversion of signed constants to unsigned ones is prohibited"); + MAP.put(INTEGER_OPERATOR_RESOLVE_WILL_CHANGE, "This expression will be resolved to {0} in further releases. Please add explicit convention call", RENDER_TYPE); MAP.put(RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS, "Left-hand side of callable reference matches expression syntax reserved for future releases"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt index 8e9a5ffe72c..c7870622209 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt @@ -58,7 +58,8 @@ private val DEFAULT_CALL_CHECKERS = listOf( NamedFunAsExpressionChecker, ContractNotAllowedCallChecker, ReifiedTypeParameterSubstitutionChecker(), MissingDependencySupertypeChecker.ForCalls, AbstractClassInstantiationChecker, SuspendConversionCallChecker, UnitConversionCallChecker, FunInterfaceConstructorReferenceChecker, NullableExtensionOperatorWithSafeCallChecker, - ReferencingToUnderscoreNamedParameterOfCatchBlockChecker, VarargWrongExecutionOrderChecker, SelfCallInNestedObjectConstructorChecker + ReferencingToUnderscoreNamedParameterOfCatchBlockChecker, VarargWrongExecutionOrderChecker, SelfCallInNestedObjectConstructorChecker, + NewSchemeOfIntegerOperatorResolutionChecker ) private val DEFAULT_TYPE_CHECKERS = emptyList() private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/NewSchemeOfIntegerOperatorResolutionChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/NewSchemeOfIntegerOperatorResolutionChecker.kt new file mode 100644 index 00000000000..c8b5e255930 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/NewSchemeOfIntegerOperatorResolutionChecker.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.resolve.calls.checkers + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtConstantExpression +import org.jetbrains.kotlin.psi.KtUnaryExpression +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall +import org.jetbrains.kotlin.resolve.calls.components.isVararg +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor +import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe + +object NewSchemeOfIntegerOperatorResolutionChecker : CallChecker { + override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) { + if (context.languageVersionSettings.supportsFeature(LanguageFeature.ApproximateIntegerLiteralTypesInReceiverPosition)) return + val bindingContext = context.trace.bindingContext + for ((valueParameter, arguments) in resolvedCall.valueArguments) { + val expectedType = if (valueParameter.isVararg) { + valueParameter.varargElementType ?: continue + } else { + valueParameter.type + }.unwrap() + for (argument in arguments.arguments) { + val expression = argument.getArgumentExpression() ?: continue + val compileTimeValue = + bindingContext[BindingContext.COMPILE_TIME_VALUE, expression] as? IntegerValueTypeConstant? ?: continue + val callForArgument = expression.getResolvedCall(bindingContext) ?: continue + if (!callForArgument.isIntOperator()) continue + val callElement = callForArgument.call.callElement + if (callElement is KtConstantExpression) continue + if (callElement is KtUnaryExpression) { + val token = callElement.operationToken + if (token == KtTokens.PLUS || token == KtTokens.MINUS) continue + } + + val valueTypeConstructor = compileTimeValue.unknownIntegerType.constructor as? IntegerLiteralTypeConstructor ?: continue + val approximatedType = valueTypeConstructor.getApproximatedType() + if (approximatedType != expectedType) { + context.trace.report(Errors.INTEGER_OPERATOR_RESOLVE_WILL_CHANGE.on(expression, approximatedType)) + } + } + } + } + + private fun ResolvedCall<*>.isIntOperator(): Boolean { + val descriptor = resultingDescriptor as? SimpleFunctionDescriptor ?: return false + return descriptor.fqNameSafe in literalOperatorsFqNames + } + + private val literalOperatorsFqNames: Set = listOf( + "plus", "minus", "times", "div", "rem", "plus", "minus", + "times", "div", "rem", "shl", "shr", "ushr", "and", "or", + "xor", "unaryPlus", "unaryMinus", "inv", + ).mapTo(mutableSetOf()) { FqName.fromSegments(listOf("kotlin", "Int", it)) } + +} + diff --git a/compiler/testData/diagnostics/tests/evaluate/binaryMinusDepOnExpType.kt b/compiler/testData/diagnostics/tests/evaluate/binaryMinusDepOnExpType.kt index 9a9aa2db970..dbdd433d5a0 100644 --- a/compiler/testData/diagnostics/tests/evaluate/binaryMinusDepOnExpType.kt +++ b/compiler/testData/diagnostics/tests/evaluate/binaryMinusDepOnExpType.kt @@ -10,19 +10,19 @@ fun test() { fooInt(1 - 1.toLong()) fooInt(1 - 1.toShort()) - fooByte(1 - 1) + fooByte(1 - 1) fooByte(1 - 1.toInt()) fooByte(1 - 1.toByte()) fooByte(1 - 1.toLong()) fooByte(1 - 1.toShort()) - fooLong(1 - 1) + fooLong(1 - 1) fooLong(1 - 1.toInt()) fooLong(1 - 1.toByte()) fooLong(1 - 1.toLong()) fooLong(1 - 1.toShort()) - fooShort(1 - 1) + fooShort(1 - 1) fooShort(1 - 1.toInt()) fooShort(1 - 1.toByte()) fooShort(1 - 1.toLong()) diff --git a/compiler/testData/diagnostics/tests/evaluate/inlineClasses/constructorOfUnsignedType.kt b/compiler/testData/diagnostics/tests/evaluate/inlineClasses/constructorOfUnsignedType.kt index 93a6181771c..0d6b247ecc1 100644 --- a/compiler/testData/diagnostics/tests/evaluate/inlineClasses/constructorOfUnsignedType.kt +++ b/compiler/testData/diagnostics/tests/evaluate/inlineClasses/constructorOfUnsignedType.kt @@ -28,7 +28,7 @@ const val ui2 = UInt(40 + 2) @AnnoUB(UByte(1), ub0) fun f0() {} -@AnnoUS(UShort(2 + 5), us0) +@AnnoUS(UShort(2 + 5), us0) fun f1() {} @AnnoUI(ui0, ui1, ui2, UInt(100)) diff --git a/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperations.kt b/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperations.kt index 1b7e3a9f8fe..dd1f3b2f3e9 100644 --- a/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperations.kt +++ b/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperations.kt @@ -5,22 +5,22 @@ fun fooShort(p: Short) = p fun test() { fooInt(1 + 1) - fooByte(1 + 1) - fooLong(1 + 1) - fooShort(1 + 1) + fooByte(1 + 1) + fooLong(1 + 1) + fooShort(1 + 1) fooInt(1 * 1) - fooByte(1 * 1) - fooLong(1 * 1) - fooShort(1 * 1) + fooByte(1 * 1) + fooLong(1 * 1) + fooShort(1 * 1) fooInt(1 / 1) - fooByte(1 / 1) - fooLong(1 / 1) - fooShort(1 / 1) + fooByte(1 / 1) + fooLong(1 / 1) + fooShort(1 / 1) fooInt(1 % 1) - fooByte(1 % 1) - fooLong(1 % 1) - fooShort(1 % 1) + fooByte(1 % 1) + fooLong(1 % 1) + fooShort(1 % 1) } diff --git a/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsCall.kt b/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsCall.kt index bec6e1a879f..b7cc68ba153 100644 --- a/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsCall.kt +++ b/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsCall.kt @@ -5,22 +5,22 @@ fun fooShort(p: Short) = p fun test() { fooInt(1.plus(1)) - fooByte(1.plus(1)) - fooLong(1.plus(1)) - fooShort(1.plus(1)) + fooByte(1.plus(1)) + fooLong(1.plus(1)) + fooShort(1.plus(1)) fooInt(1.times(1)) - fooByte(1.times(1)) - fooLong(1.times(1)) - fooShort(1.times(1)) + fooByte(1.times(1)) + fooLong(1.times(1)) + fooShort(1.times(1)) fooInt(1.div(1)) - fooByte(1.div(1)) - fooLong(1.div(1)) - fooShort(1.div(1)) + fooByte(1.div(1)) + fooLong(1.div(1)) + fooShort(1.div(1)) fooInt(1.rem(1)) - fooByte(1.rem(1)) - fooLong(1.rem(1)) - fooShort(1.rem(1)) + fooByte(1.rem(1)) + fooLong(1.rem(1)) + fooShort(1.rem(1)) } diff --git a/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsInfixCall.kt b/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsInfixCall.kt index 28abfb82456..d3c96b424d7 100644 --- a/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsInfixCall.kt +++ b/compiler/testData/diagnostics/tests/evaluate/numberBinaryOperationsInfixCall.kt @@ -5,22 +5,22 @@ fun fooShort(p: Short) = p fun test() { fooInt(1 plus 1) - fooByte(1 plus 1) - fooLong(1 plus 1) - fooShort(1 plus 1) + fooByte(1 plus 1) + fooLong(1 plus 1) + fooShort(1 plus 1) fooInt(1 times 1) - fooByte(1 times 1) - fooLong(1 times 1) - fooShort(1 times 1) + fooByte(1 times 1) + fooLong(1 times 1) + fooShort(1 times 1) fooInt(1 div 1) - fooByte(1 div 1) - fooLong(1 div 1) - fooShort(1 div 1) + fooByte(1 div 1) + fooLong(1 div 1) + fooShort(1 div 1) fooInt(1 rem 1) - fooByte(1 rem 1) - fooLong(1 rem 1) - fooShort(1 rem 1) + fooByte(1 rem 1) + fooLong(1 rem 1) + fooShort(1 rem 1) } diff --git a/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt b/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt index 498a7380b01..e91b113836d 100644 --- a/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt +++ b/compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt @@ -6,62 +6,62 @@ abstract class C { } 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.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()) + 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.plus(2)) c2.takeT(1.inc()) c2.takeT(1.dec()) - c2.takeT(1.shr(2)) - c2.takeT(1.inv()) + c2.takeT(1.shr(2)) + c2.takeT(1.inv()) } fun testByteDotCall(c3: C) { - c3.takeT(1.plus(2)) + c3.takeT(1.plus(2)) c3.takeT(1.inc()) c3.takeT(1.dec()) - c3.takeT(1.shr(2)) - c3.takeT(1.inv()) + 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 + 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) + 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) + c5.takeT(1 + 2) + c5.takeT(1 shr 2) } fun testByteOperatorInfixCall(c6: C) { - c6.takeT(1 + 2) - c6.takeT(1 shr 2) + c6.takeT(1 + 2) + c6.takeT(1 shr 2) } diff --git a/compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_warning.fir.kt b/compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_warning.fir.kt new file mode 100644 index 00000000000..b49fa39773a --- /dev/null +++ b/compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_warning.fir.kt @@ -0,0 +1,116 @@ +// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition +// WITH_STDLIB +// ISSUE: KT-38895 + +fun takeByte(b: Byte) {} +fun takeInt(b: Int) {} +fun takeLong(b: Long) {} + +fun testByteBinaryOperators() { + takeByte(2 + 1) + takeByte(2 - 1) + takeByte(2 * 1) + takeByte(2 / 1) + takeByte(2 % 1) + + takeByte(2.plus(1)) + takeByte(2.minus(1)) + takeByte(2.times(1)) + takeByte(2.div(1)) + takeByte(2.rem(1)) + takeByte(2 shl 1) + takeByte(2 shr 1) + takeByte(2 ushr 1) + + takeByte(2 and 1) + takeByte(2 or 1) + takeByte(2 xor 1) +} + +fun testByteUnaryOperators() { + // Won't change + takeByte(+1) + takeByte(-1) + + // Will change + takeByte(2.unaryPlus()) + takeByte(2.unaryMinus()) + takeByte(2.inv()) + takeByte(1.inc()) + takeByte(1.dec()) +} + +fun testLongBinaryOperators() { + takeLong(2 + 1) + takeLong(2 - 1) + takeLong(2 * 1) + takeLong(2 / 1) + takeLong(2 % 1) + + takeLong(2.plus(1)) + takeLong(2.minus(1)) + takeLong(2.times(1)) + takeLong(2.div(1)) + takeLong(2.rem(1)) + takeLong(2 shl 1) + takeLong(2 shr 1) + takeLong(2 ushr 1) + + takeLong(2 and 1) + takeLong(2 or 1) + takeLong(2 xor 1) + + // positive + takeLong(2 * 100000000000) +} + +fun testLongUnaryOperators() { + // Won't change + takeLong(+1) + takeLong(-1) + + // Will change + takeLong(2.unaryPlus()) + takeLong(2.unaryMinus()) + takeLong(2.inv()) + takeLong(1.inc()) + takeLong(1.dec()) +} + +fun testIntBinaryOperators() { + takeInt(2 + 1) + takeInt(2 - 1) + takeInt(2 * 1) + takeInt(2 / 1) + takeInt(2 % 1) + + takeInt(2.plus(1)) + takeInt(2.minus(1)) + takeInt(2.times(1)) + takeInt(2.div(1)) + takeInt(2.rem(1)) + takeInt(2 shl 1) + takeInt(2 shr 1) + takeInt(2 ushr 1) + + takeInt(2 and 1) + takeInt(2 or 1) + takeInt(2 xor 1) +} + +fun testIntUnaryOperators() { + takeInt(+1) + takeInt(-1) + + takeInt(2.unaryPlus()) + takeInt(2.unaryMinus()) + takeInt(2.inv()) + takeInt(1.inc()) + takeInt(1.dec()) +} + +fun testNoOperators() { + takeByte(1) + takeInt(1) + takeLong(1) +} diff --git a/compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_warning.kt b/compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_warning.kt new file mode 100644 index 00000000000..286fff0ff56 --- /dev/null +++ b/compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_warning.kt @@ -0,0 +1,116 @@ +// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition +// WITH_STDLIB +// ISSUE: KT-38895 + +fun takeByte(b: Byte) {} +fun takeInt(b: Int) {} +fun takeLong(b: Long) {} + +fun testByteBinaryOperators() { + takeByte(2 + 1) + takeByte(2 - 1) + takeByte(2 * 1) + takeByte(2 / 1) + takeByte(2 % 1) + + takeByte(2.plus(1)) + takeByte(2.minus(1)) + takeByte(2.times(1)) + takeByte(2.div(1)) + takeByte(2.rem(1)) + takeByte(2 shl 1) + takeByte(2 shr 1) + takeByte(2 ushr 1) + + takeByte(2 and 1) + takeByte(2 or 1) + takeByte(2 xor 1) +} + +fun testByteUnaryOperators() { + // Won't change + takeByte(+1) + takeByte(-1) + + // Will change + takeByte(2.unaryPlus()) + takeByte(2.unaryMinus()) + takeByte(2.inv()) + takeByte(1.inc()) + takeByte(1.dec()) +} + +fun testLongBinaryOperators() { + takeLong(2 + 1) + takeLong(2 - 1) + takeLong(2 * 1) + takeLong(2 / 1) + takeLong(2 % 1) + + takeLong(2.plus(1)) + takeLong(2.minus(1)) + takeLong(2.times(1)) + takeLong(2.div(1)) + takeLong(2.rem(1)) + takeLong(2 shl 1) + takeLong(2 shr 1) + takeLong(2 ushr 1) + + takeLong(2 and 1) + takeLong(2 or 1) + takeLong(2 xor 1) + + // positive + takeLong(2 * 100000000000) +} + +fun testLongUnaryOperators() { + // Won't change + takeLong(+1) + takeLong(-1) + + // Will change + takeLong(2.unaryPlus()) + takeLong(2.unaryMinus()) + takeLong(2.inv()) + takeLong(1.inc()) + takeLong(1.dec()) +} + +fun testIntBinaryOperators() { + takeInt(2 + 1) + takeInt(2 - 1) + takeInt(2 * 1) + takeInt(2 / 1) + takeInt(2 % 1) + + takeInt(2.plus(1)) + takeInt(2.minus(1)) + takeInt(2.times(1)) + takeInt(2.div(1)) + takeInt(2.rem(1)) + takeInt(2 shl 1) + takeInt(2 shr 1) + takeInt(2 ushr 1) + + takeInt(2 and 1) + takeInt(2 or 1) + takeInt(2 xor 1) +} + +fun testIntUnaryOperators() { + takeInt(+1) + takeInt(-1) + + takeInt(2.unaryPlus()) + takeInt(2.unaryMinus()) + takeInt(2.inv()) + takeInt(1.inc()) + takeInt(1.dec()) +} + +fun testNoOperators() { + takeByte(1) + takeInt(1) + takeLong(1) +} diff --git a/compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_warning.txt b/compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_warning.txt new file mode 100644 index 00000000000..383ce572178 --- /dev/null +++ b/compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_warning.txt @@ -0,0 +1,13 @@ +package + +public fun takeByte(/*0*/ b: kotlin.Byte): kotlin.Unit +public fun takeInt(/*0*/ b: kotlin.Int): kotlin.Unit +public fun takeLong(/*0*/ b: kotlin.Long): kotlin.Unit +public fun testByteBinaryOperators(): kotlin.Unit +public fun testByteUnaryOperators(): kotlin.Unit +public fun testIntBinaryOperators(): kotlin.Unit +public fun testIntUnaryOperators(): kotlin.Unit +public fun testLongBinaryOperators(): kotlin.Unit +public fun testLongUnaryOperators(): kotlin.Unit +public fun testNoOperators(): kotlin.Unit + diff --git a/compiler/testData/diagnostics/tests/operatorRem/numberRemConversions.kt b/compiler/testData/diagnostics/tests/operatorRem/numberRemConversions.kt index 468608b6a21..6ea95abe126 100644 --- a/compiler/testData/diagnostics/tests/operatorRem/numberRemConversions.kt +++ b/compiler/testData/diagnostics/tests/operatorRem/numberRemConversions.kt @@ -7,9 +7,9 @@ fun fooShort(p: Short) = p fun test() { fooInt(1 % 1) - fooByte(1 % 1) - fooLong(1 % 1) - fooShort(1 % 1) + fooByte(1 % 1) + fooLong(1 % 1) + fooShort(1 % 1) } public operator fun Int.rem(other: Int): Int = 0 diff --git a/compiler/testData/diagnostics/tests/unsignedTypes/conversions/signedToUnsignedConversionWithExpectedType.kt b/compiler/testData/diagnostics/tests/unsignedTypes/conversions/signedToUnsignedConversionWithExpectedType.kt index 66f235dc915..d6670de366b 100644 --- a/compiler/testData/diagnostics/tests/unsignedTypes/conversions/signedToUnsignedConversionWithExpectedType.kt +++ b/compiler/testData/diagnostics/tests/unsignedTypes/conversions/signedToUnsignedConversionWithExpectedType.kt @@ -34,7 +34,7 @@ fun test() { takeUInt(Int.MAX_VALUE * 2) takeUInt(4294967294) - takeUBytes(1, 2, 255, 256, 0, -1, 40 + 2) + takeUBytes(1, 2, 255, 256, 0, -1, 40 + 2) takeUInt(1.myPlus(2)) diff --git a/compiler/testData/diagnostics/testsWithJsStdLib/jsCode/argumentIsLiteral.kt b/compiler/testData/diagnostics/testsWithJsStdLib/jsCode/argumentIsLiteral.kt index a66646c4d9c..eadb4f2ac9b 100644 --- a/compiler/testData/diagnostics/testsWithJsStdLib/jsCode/argumentIsLiteral.kt +++ b/compiler/testData/diagnostics/testsWithJsStdLib/jsCode/argumentIsLiteral.kt @@ -9,7 +9,7 @@ fun test() { js((b)) js(("c")) js(3) - js(3 + 2) + js(3 + 2) js(1.0f) js(true) js("$a") @@ -21,4 +21,4 @@ fun test() { js("ccc") js(nonConst()) -} \ No newline at end of file +} 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 2c55f44ebef..677b0fb815f 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 @@ -19093,6 +19093,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/numbers/literalReceiverWithIntegerValueType.kt"); } + @Test + @TestMetadata("newLiteralOperatorsResolution_warning.kt") + public void testNewLiteralOperatorsResolution_warning() throws Exception { + runTest("compiler/testData/diagnostics/tests/numbers/newLiteralOperatorsResolution_warning.kt"); + } + @Test @TestMetadata("numberAsUnionAndIntersection.kt") public void testNumberAsUnionAndIntersection() throws Exception { diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index a23d3c83b66..2867d9d2177 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -167,6 +167,7 @@ enum class LanguageFeature( PrivateInFileEffectiveVisibility(KOTLIN_1_6, kind = BUG_FIX), ForbidUsingExtensionPropertyTypeParameterInDelegate(KOTLIN_1_6, kind = BUG_FIX), ProhibitSelfCallsInNestedObjects(KOTLIN_1_6, kind = BUG_FIX), + ApproximateIntegerLiteralTypesInReceiverPosition(KOTLIN_1_6), // Temporarily disabled, see KT-27084/KT-22379 SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),