Postpone conversions from signed constants to unsigned ones
#KT-26071 Fixed
This commit is contained in:
@@ -911,6 +911,7 @@ public interface Errors {
|
||||
DiagnosticFactory1<KtConstantExpression, KotlinType> NULL_FOR_NONNULL_TYPE = DiagnosticFactory1.create(ERROR);
|
||||
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);
|
||||
|
||||
|
||||
// Casts and is-checks
|
||||
|
||||
+1
@@ -388,6 +388,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(NOT_A_CLASS, "Not a class");
|
||||
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(RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS, "Left-hand side of callable reference matches expression syntax reserved for future releases");
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.CONSTRAINT_SYSTEM_COMPLETER
|
||||
@@ -321,10 +322,15 @@ class CallCompleter(
|
||||
|
||||
val results = completeCallForArgument(deparenthesized, context)
|
||||
|
||||
val constant = context.trace[BindingContext.COMPILE_TIME_VALUE, deparenthesized]
|
||||
val convertedConst = constant is IntegerValueTypeConstant && constant.convertedFromSigned
|
||||
if (convertedConst) {
|
||||
context.trace.report(Errors.SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED.on(deparenthesized))
|
||||
}
|
||||
|
||||
if (results != null && results.isSingleResult) {
|
||||
val resolvedCall = results.resultingCall
|
||||
val constant = context.trace[BindingContext.COMPILE_TIME_VALUE, deparenthesized]
|
||||
if (constant !is IntegerValueTypeConstant || !constant.convertedFromSigned) {
|
||||
if (!convertedConst) {
|
||||
updatedType =
|
||||
if (resolvedCall.hasInferredReturnType())
|
||||
resolvedCall.makeNullableTypeIfSafeReceiver(resolvedCall.resultingDescriptor?.returnType, context)
|
||||
|
||||
+2
@@ -1,6 +1,8 @@
|
||||
// WITH_UNSIGNED
|
||||
// IGNORE_BACKEND: JS_IR, JVM_IR
|
||||
|
||||
@file:Suppress("SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED")
|
||||
|
||||
fun takeUByte(u: UByte) = u.toByte()
|
||||
fun takeUShort(u: UShort) = u.toShort()
|
||||
fun takeUInt(u: UInt) = u.toInt()
|
||||
|
||||
+1
-1
@@ -13,5 +13,5 @@ fun foo() {
|
||||
takeUByte(<!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>id(1)<!>)
|
||||
|
||||
1 <!NONE_APPLICABLE!>+<!> 1u
|
||||
(1u + 1) checkType { _<UInt>() }
|
||||
(1u + <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>) checkType { _<UInt>() }
|
||||
}
|
||||
+1
-1
@@ -25,7 +25,7 @@ fun test() {
|
||||
foo(1) checkType { _<Int>() }
|
||||
foo(1u) checkType { _<String>() }
|
||||
|
||||
foo(2147483648) checkType { _<String>() }
|
||||
foo(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>2147483648<!>) checkType { _<String>() }
|
||||
foo(<!INTEGER_OVERFLOW!>2147483647 + 1<!>) checkType { _<Int>() }
|
||||
|
||||
fooByte(1) checkType { _<Int>() }
|
||||
|
||||
+12
-12
@@ -10,30 +10,30 @@ fun takeUBytes(vararg u: UByte) {}
|
||||
fun takeNullableUInt(u: UInt?) {}
|
||||
|
||||
fun test() {
|
||||
takeUInt(1 + 2)
|
||||
takeUInt(1.plus(2))
|
||||
takeNullableUInt(4)
|
||||
takeUInt(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1 + 2<!>)
|
||||
takeUInt(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1.plus(2)<!>)
|
||||
takeNullableUInt(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>4<!>)
|
||||
|
||||
takeUInt(<!TYPE_MISMATCH!>Int.MAX_VALUE * 2L<!>)
|
||||
takeUInt(<!TYPE_MISMATCH!>-1<!>)
|
||||
takeUInt(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED, TYPE_MISMATCH!>-1<!>)
|
||||
takeUInt(<!TYPE_MISMATCH!>Int.MAX_VALUE * 2L + 2<!>)
|
||||
|
||||
takeUByte(1)
|
||||
takeUByte(255)
|
||||
takeUByte(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>)
|
||||
takeUByte(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>255<!>)
|
||||
takeUByte(<!TYPE_MISMATCH!>1.toByte()<!>)
|
||||
|
||||
takeUShort(1)
|
||||
takeUInt(1)
|
||||
takeULong(1)
|
||||
takeUShort(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>)
|
||||
takeUInt(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>)
|
||||
takeULong(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>)
|
||||
|
||||
takeULong(<!INT_LITERAL_OUT_OF_RANGE!>18446744073709551615<!>)
|
||||
takeULong(1844674407370955161)
|
||||
takeULong(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1844674407370955161<!>)
|
||||
takeULong(18446744073709551615u)
|
||||
|
||||
takeUInt(<!INTEGER_OVERFLOW, TYPE_MISMATCH!>Int.MAX_VALUE * 2<!>)
|
||||
takeUInt(4294967294)
|
||||
takeUInt(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>4294967294<!>)
|
||||
|
||||
takeUBytes(1, 2, 255, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>256<!>, 0, <!TYPE_MISMATCH!>-1<!>, 40 + 2)
|
||||
takeUBytes(<!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>1<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>2<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>255<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED, CONSTANT_EXPECTED_TYPE_MISMATCH!>256<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>0<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED, TYPE_MISMATCH!>-1<!>, <!SIGNED_CONSTANT_CONVERTED_TO_UNSIGNED!>40 + 2<!>)
|
||||
|
||||
takeUInt(<!TYPE_MISMATCH!>1.myPlus(2)<!>)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user