Add deprecation warning about new integer operators on literals resolution
#KT-38895
This commit is contained in:
committed by
TeamCityServer
parent
53b6d6f767
commit
6afb905ad6
+6
@@ -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 {
|
||||
|
||||
@@ -1017,6 +1017,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtEscapeStringTemplateEntry> ILLEGAL_ESCAPE_SEQUENCE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtConstantExpression> UNSIGNED_LITERAL_WITHOUT_DECLARATIONS_ON_CLASSPATH = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtExpression> SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory1<KtExpression, KotlinType> INTEGER_OPERATOR_RESOLVE_WILL_CHANGE = DiagnosticFactory1.create(WARNING);
|
||||
|
||||
|
||||
// Casts and is-checks
|
||||
|
||||
+1
@@ -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");
|
||||
|
||||
|
||||
@@ -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<AdditionalTypeChecker>()
|
||||
private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(
|
||||
|
||||
+68
@@ -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<FqName> = 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)) }
|
||||
|
||||
}
|
||||
|
||||
@@ -10,19 +10,19 @@ fun test() {
|
||||
fooInt(<!TYPE_MISMATCH!>1 - 1.toLong()<!>)
|
||||
fooInt(1 - 1.toShort())
|
||||
|
||||
fooByte(1 - 1)
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 - 1<!>)
|
||||
fooByte(<!TYPE_MISMATCH!>1 - 1.toInt()<!>)
|
||||
fooByte(<!TYPE_MISMATCH!>1 - 1.toByte()<!>)
|
||||
fooByte(<!TYPE_MISMATCH!>1 - 1.toLong()<!>)
|
||||
fooByte(<!TYPE_MISMATCH!>1 - 1.toShort()<!>)
|
||||
|
||||
fooLong(1 - 1)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 - 1<!>)
|
||||
fooLong(<!TYPE_MISMATCH!>1 - 1.toInt()<!>)
|
||||
fooLong(<!TYPE_MISMATCH!>1 - 1.toByte()<!>)
|
||||
fooLong(1 - 1.toLong())
|
||||
fooLong(<!TYPE_MISMATCH!>1 - 1.toShort()<!>)
|
||||
|
||||
fooShort(1 - 1)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 - 1<!>)
|
||||
fooShort(<!TYPE_MISMATCH!>1 - 1.toInt()<!>)
|
||||
fooShort(<!TYPE_MISMATCH!>1 - 1.toByte()<!>)
|
||||
fooShort(<!TYPE_MISMATCH!>1 - 1.toLong()<!>)
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ const val ui2 = UInt(40 + 2)
|
||||
@AnnoUB(UByte(1), ub0)
|
||||
fun f0() {}
|
||||
|
||||
@AnnoUS(UShort(2 + 5), us0)
|
||||
@AnnoUS(UShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 + 5<!>), us0)
|
||||
fun f1() {}
|
||||
|
||||
@AnnoUI(ui0, ui1, ui2, UInt(100))
|
||||
|
||||
@@ -5,22 +5,22 @@ fun fooShort(p: Short) = p
|
||||
|
||||
fun test() {
|
||||
fooInt(1 + 1)
|
||||
fooByte(1 + 1)
|
||||
fooLong(1 + 1)
|
||||
fooShort(1 + 1)
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 + 1<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 + 1<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 + 1<!>)
|
||||
|
||||
fooInt(1 * 1)
|
||||
fooByte(1 * 1)
|
||||
fooLong(1 * 1)
|
||||
fooShort(1 * 1)
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 * 1<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 * 1<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 * 1<!>)
|
||||
|
||||
fooInt(1 / 1)
|
||||
fooByte(1 / 1)
|
||||
fooLong(1 / 1)
|
||||
fooShort(1 / 1)
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 / 1<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 / 1<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 / 1<!>)
|
||||
|
||||
fooInt(1 % 1)
|
||||
fooByte(1 % 1)
|
||||
fooLong(1 % 1)
|
||||
fooShort(1 % 1)
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 % 1<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 % 1<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 % 1<!>)
|
||||
}
|
||||
|
||||
+12
-12
@@ -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(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.plus(1)<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.plus(1)<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.plus(1)<!>)
|
||||
|
||||
fooInt(1.times(1))
|
||||
fooByte(1.times(1))
|
||||
fooLong(1.times(1))
|
||||
fooShort(1.times(1))
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.times(1)<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.times(1)<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.times(1)<!>)
|
||||
|
||||
fooInt(1.div(1))
|
||||
fooByte(1.div(1))
|
||||
fooLong(1.div(1))
|
||||
fooShort(1.div(1))
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.div(1)<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.div(1)<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.div(1)<!>)
|
||||
|
||||
fooInt(1.rem(1))
|
||||
fooByte(1.rem(1))
|
||||
fooLong(1.rem(1))
|
||||
fooShort(1.rem(1))
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.rem(1)<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.rem(1)<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.rem(1)<!>)
|
||||
}
|
||||
|
||||
+12
-12
@@ -5,22 +5,22 @@ fun fooShort(p: Short) = p
|
||||
|
||||
fun test() {
|
||||
fooInt(1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1)
|
||||
fooByte(1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1)
|
||||
fooLong(1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1)
|
||||
fooShort(1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1)
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 <!INFIX_MODIFIER_REQUIRED!>plus<!> 1<!>)
|
||||
|
||||
fooInt(1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1)
|
||||
fooByte(1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1)
|
||||
fooLong(1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1)
|
||||
fooShort(1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1)
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 <!INFIX_MODIFIER_REQUIRED!>times<!> 1<!>)
|
||||
|
||||
fooInt(1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1)
|
||||
fooByte(1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1)
|
||||
fooLong(1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1)
|
||||
fooShort(1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1)
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 <!INFIX_MODIFIER_REQUIRED!>div<!> 1<!>)
|
||||
|
||||
fooInt(1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1)
|
||||
fooByte(1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1)
|
||||
fooLong(1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1)
|
||||
fooShort(1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1)
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 <!INFIX_MODIFIER_REQUIRED!>rem<!> 1<!>)
|
||||
}
|
||||
|
||||
+35
-35
@@ -6,62 +6,62 @@ abstract class C<L> {
|
||||
}
|
||||
|
||||
fun testLongDotCall(c1: C<Long>) {
|
||||
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(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.plus(2)<!>)
|
||||
c1.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.minus(2)<!>)
|
||||
c1.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.times(2)<!>)
|
||||
c1.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.div(2)<!>)
|
||||
c1.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.rem(2)<!>)
|
||||
c1.takeT(<!TYPE_MISMATCH!>1.inc()<!>)
|
||||
c1.takeT(<!TYPE_MISMATCH!>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(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.unaryPlus()<!>)
|
||||
c1.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.unaryMinus()<!>)
|
||||
c1.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.shl(2)<!>)
|
||||
c1.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.shr(2)<!>)
|
||||
c1.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.ushr(2)<!>)
|
||||
c1.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.and(2)<!>)
|
||||
c1.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.or(2)<!>)
|
||||
c1.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.xor(2)<!>)
|
||||
c1.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.inv()<!>)
|
||||
}
|
||||
|
||||
fun testShortDotCall(c2: C<Short>) {
|
||||
c2.takeT(1.plus(2))
|
||||
c2.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.plus(2)<!>)
|
||||
c2.takeT(<!TYPE_MISMATCH!>1.inc()<!>)
|
||||
c2.takeT(<!TYPE_MISMATCH!>1.dec()<!>)
|
||||
c2.takeT(1.shr(2))
|
||||
c2.takeT(1.inv())
|
||||
c2.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.shr(2)<!>)
|
||||
c2.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.inv()<!>)
|
||||
}
|
||||
|
||||
fun testByteDotCall(c3: C<Byte>) {
|
||||
c3.takeT(1.plus(2))
|
||||
c3.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.plus(2)<!>)
|
||||
c3.takeT(<!TYPE_MISMATCH!>1.inc()<!>)
|
||||
c3.takeT(<!TYPE_MISMATCH!>1.dec()<!>)
|
||||
c3.takeT(1.shr(2))
|
||||
c3.takeT(1.inv())
|
||||
c3.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.shr(2)<!>)
|
||||
c3.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1.inv()<!>)
|
||||
}
|
||||
|
||||
fun testLongOperatorInfixCall(c4: C<Long>) {
|
||||
c4.takeT(1 + 2)
|
||||
c4.takeT(1 - 2)
|
||||
c4.takeT(1 * 2)
|
||||
c4.takeT(1 / 2)
|
||||
c4.takeT(1 % 2)
|
||||
c4.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 + 2<!>)
|
||||
c4.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 - 2<!>)
|
||||
c4.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 * 2<!>)
|
||||
c4.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 / 2<!>)
|
||||
c4.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>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(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 shl 2<!>)
|
||||
c4.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 shr 2<!>)
|
||||
c4.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 ushr 2<!>)
|
||||
c4.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 and 2<!>)
|
||||
c4.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 or 2<!>)
|
||||
c4.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 xor 2<!>)
|
||||
}
|
||||
|
||||
fun testShortOperatorInfixCall(c5: C<Short>) {
|
||||
c5.takeT(1 + 2)
|
||||
c5.takeT(1 shr 2)
|
||||
c5.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 + 2<!>)
|
||||
c5.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 shr 2<!>)
|
||||
}
|
||||
|
||||
fun testByteOperatorInfixCall(c6: C<Byte>) {
|
||||
c6.takeT(1 + 2)
|
||||
c6.takeT(1 shr 2)
|
||||
c6.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 + 2<!>)
|
||||
c6.takeT(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 shr 2<!>)
|
||||
}
|
||||
|
||||
+116
@@ -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(<!ARGUMENT_TYPE_MISMATCH!>2 + 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 - 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 * 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 / 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 % 1<!>)
|
||||
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.plus(1)<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.minus(1)<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.times(1)<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.div(1)<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.rem(1)<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 shl 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 shr 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 ushr 1<!>)
|
||||
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 and 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 or 1<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2 xor 1<!>)
|
||||
}
|
||||
|
||||
fun testByteUnaryOperators() {
|
||||
// Won't change
|
||||
takeByte(+1)
|
||||
takeByte(-1)
|
||||
|
||||
// Will change
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.unaryPlus()<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.unaryMinus()<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>2.inv()<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>1.inc()<!>)
|
||||
takeByte(<!ARGUMENT_TYPE_MISMATCH!>1.dec()<!>)
|
||||
}
|
||||
|
||||
fun testLongBinaryOperators() {
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 + 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 - 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 * 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 / 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 % 1<!>)
|
||||
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.plus(1)<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.minus(1)<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.times(1)<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.div(1)<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.rem(1)<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 shl 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 shr 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 ushr 1<!>)
|
||||
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 and 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 or 1<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2 xor 1<!>)
|
||||
|
||||
// positive
|
||||
takeLong(2 * 100000000000)
|
||||
}
|
||||
|
||||
fun testLongUnaryOperators() {
|
||||
// Won't change
|
||||
takeLong(+1)
|
||||
takeLong(-1)
|
||||
|
||||
// Will change
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.unaryPlus()<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.unaryMinus()<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>2.inv()<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>1.inc()<!>)
|
||||
takeLong(<!ARGUMENT_TYPE_MISMATCH!>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)
|
||||
}
|
||||
+116
@@ -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(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 + 1<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 - 1<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 * 1<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 / 1<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 % 1<!>)
|
||||
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.plus(1)<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.minus(1)<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.times(1)<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.div(1)<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.rem(1)<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 shl 1<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 shr 1<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 ushr 1<!>)
|
||||
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 and 1<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 or 1<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 xor 1<!>)
|
||||
}
|
||||
|
||||
fun testByteUnaryOperators() {
|
||||
// Won't change
|
||||
takeByte(+1)
|
||||
takeByte(-1)
|
||||
|
||||
// Will change
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.unaryPlus()<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.unaryMinus()<!>)
|
||||
takeByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.inv()<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>1.inc()<!>)
|
||||
takeByte(<!TYPE_MISMATCH!>1.dec()<!>)
|
||||
}
|
||||
|
||||
fun testLongBinaryOperators() {
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 + 1<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 - 1<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 * 1<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 / 1<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 % 1<!>)
|
||||
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.plus(1)<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.minus(1)<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.times(1)<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.div(1)<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.rem(1)<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 shl 1<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 shr 1<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 ushr 1<!>)
|
||||
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 and 1<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 or 1<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2 xor 1<!>)
|
||||
|
||||
// positive
|
||||
takeLong(2 * 100000000000)
|
||||
}
|
||||
|
||||
fun testLongUnaryOperators() {
|
||||
// Won't change
|
||||
takeLong(+1)
|
||||
takeLong(-1)
|
||||
|
||||
// Will change
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.unaryPlus()<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.unaryMinus()<!>)
|
||||
takeLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>2.inv()<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>1.inc()<!>)
|
||||
takeLong(<!TYPE_MISMATCH!>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)
|
||||
}
|
||||
+13
@@ -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
|
||||
|
||||
@@ -7,9 +7,9 @@ fun fooShort(p: Short) = p
|
||||
|
||||
fun test() {
|
||||
fooInt(1 % 1)
|
||||
fooByte(1 % 1)
|
||||
fooLong(1 % 1)
|
||||
fooShort(1 % 1)
|
||||
fooByte(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 % 1<!>)
|
||||
fooLong(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 % 1<!>)
|
||||
fooShort(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>1 % 1<!>)
|
||||
}
|
||||
|
||||
public operator fun Int.<!EXTENSION_SHADOWED_BY_MEMBER!>rem<!>(other: Int): Int = 0
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ fun test() {
|
||||
takeUInt(<!INTEGER_OVERFLOW, TYPE_MISMATCH!>Int.MAX_VALUE * 2<!>)
|
||||
takeUInt(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>4294967294<!>)
|
||||
|
||||
takeUBytes(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>2<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>255<!>, <!CONSTANT_EXPECTED_TYPE_MISMATCH, SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>256<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>0<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED, TYPE_MISMATCH!>-1<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>40 + 2<!>)
|
||||
takeUBytes(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>2<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>255<!>, <!CONSTANT_EXPECTED_TYPE_MISMATCH, SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>256<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>0<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED, TYPE_MISMATCH!>-1<!>, <!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE, SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>40 + 2<!>)
|
||||
|
||||
takeUInt(<!TYPE_MISMATCH!>1.myPlus(2)<!>)
|
||||
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ fun test() {
|
||||
js((b))
|
||||
js(("c"))
|
||||
js(<!CONSTANT_EXPECTED_TYPE_MISMATCH, JSCODE_ARGUMENT_SHOULD_BE_CONSTANT!>3<!>)
|
||||
js(<!JSCODE_ARGUMENT_SHOULD_BE_CONSTANT, TYPE_MISMATCH!>3 + 2<!>)
|
||||
js(<!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE, JSCODE_ARGUMENT_SHOULD_BE_CONSTANT, TYPE_MISMATCH!>3 + 2<!>)
|
||||
js(<!CONSTANT_EXPECTED_TYPE_MISMATCH, JSCODE_ARGUMENT_SHOULD_BE_CONSTANT!>1.0f<!>)
|
||||
js(<!CONSTANT_EXPECTED_TYPE_MISMATCH, JSCODE_ARGUMENT_SHOULD_BE_CONSTANT!>true<!>)
|
||||
js("$a")
|
||||
@@ -21,4 +21,4 @@ fun test() {
|
||||
js("ccc")
|
||||
|
||||
js(<!JSCODE_ARGUMENT_SHOULD_BE_CONSTANT!>nonConst()<!>)
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+6
@@ -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 {
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user