Postpone conversions from signed constants to unsigned ones

#KT-26071 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2018-08-28 16:25:29 +03:00
parent d785b7e4c5
commit daadba0927
7 changed files with 26 additions and 16 deletions
@@ -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
@@ -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)