[FE 1.0] Report warning about new IL operator resolve in initializers and default values

^KT-48361 Fixed
This commit is contained in:
Dmitriy Novozhilov
2021-08-23 11:36:14 +03:00
committed by TeamCityServer
parent a15a5aa429
commit 40614507d3
29 changed files with 143 additions and 35 deletions
@@ -20257,6 +20257,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/numbers/kt47729_parenthesis.kt");
}
@Test
@TestMetadata("kt48361_disabled.kt")
public void testKt48361_disabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/numbers/kt48361_disabled.kt");
}
@Test
@TestMetadata("kt48361_enabled.kt")
public void testKt48361_enabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/numbers/kt48361_enabled.kt");
}
@Test
@TestMetadata("literalReceiverWithIntegerValueType.kt")
public void testLiteralReceiverWithIntegerValueType() throws Exception {
@@ -20257,6 +20257,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/numbers/kt47729_parenthesis.kt");
}
@Test
@TestMetadata("kt48361_disabled.kt")
public void testKt48361_disabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/numbers/kt48361_disabled.kt");
}
@Test
@TestMetadata("kt48361_enabled.kt")
public void testKt48361_enabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/numbers/kt48361_enabled.kt");
}
@Test
@TestMetadata("literalReceiverWithIntegerValueType.kt")
public void testLiteralReceiverWithIntegerValueType() throws Exception {
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtVariableDeclaration
import org.jetbrains.kotlin.resolve.DescriptorResolver.transformAnonymousTypeIfNeeded
import org.jetbrains.kotlin.resolve.calls.checkers.NewSchemeOfIntegerOperatorResolutionChecker
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
@@ -124,6 +125,13 @@ class VariableTypeAndInitializerResolver(
val initializer = variable.initializer
val initializerType =
expressionTypingServices.safeGetType(scope, initializer!!, variableType, dataFlowInfo, inferenceSession, trace)
NewSchemeOfIntegerOperatorResolutionChecker.checkArgument(
variableType,
initializer,
languageVersionSettings,
trace,
constantExpressionEvaluator.module
)
val constant = constantExpressionEvaluator.evaluateExpression(initializer, trace, initializerType)
?: return@computeInitializer null
@@ -131,7 +139,8 @@ class VariableTypeAndInitializerResolver(
trace.report(Errors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION.on(initializer))
}
constant.toConstantValue(initializerType)
val qqq = constant.toConstantValue(initializerType)
qqq
},
null
)
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve.calls.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
@@ -52,7 +53,14 @@ object NewSchemeOfIntegerOperatorResolutionChecker : CallChecker {
}
@JvmStatic
fun checkArgument(expectedType: KotlinType, argument: KtExpression, trace: BindingTrace, moduleDescriptor: ModuleDescriptor) {
fun checkArgument(
expectedType: KotlinType,
argument: KtExpression,
languageVersionSettings: LanguageVersionSettings,
trace: BindingTrace,
moduleDescriptor: ModuleDescriptor
) {
if (languageVersionSettings.supportsFeature(LanguageFeature.ApproximateIntegerLiteralTypesInReceiverPosition)) return
val type = expectedType.lowerIfFlexible()
if (type.isPrimitiveNumberOrNullableType()) {
checkArgumentImpl(type, KtPsiUtil.deparenthesize(argument)!!, trace, moduleDescriptor)
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.UnsignedTypes
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageFeature.ApproximateIntegerLiteralTypesInReceiverPosition
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
@@ -47,6 +48,7 @@ import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.types.typeUtil.isBoolean
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import java.math.BigInteger
import java.util.*
@@ -379,7 +381,7 @@ private class ConstantExpressionEvaluatorVisitor(
private val languageVersionSettings = constantExpressionEvaluator.languageVersionSettings
private val builtIns = constantExpressionEvaluator.module.builtIns
private val defaultValueForDontCreateIntegerLiteralType =
languageVersionSettings.supportsFeature(LanguageFeature.ApproximateIntegerLiteralTypesInReceiverPosition)
languageVersionSettings.supportsFeature(ApproximateIntegerLiteralTypesInReceiverPosition)
fun evaluate(expression: KtExpression, expectedType: KotlinType?): CompileTimeConstant<*>? {
val recordedCompileTimeConstant = ConstantExpressionEvaluator.getPossiblyErrorConstant(expression, trace.bindingContext)
@@ -666,10 +668,12 @@ private class ConstantExpressionEvaluatorVisitor(
val usesNonConstValAsConstant = usesNonConstValAsConstant(argumentForReceiver.expression)
val isNumberConversionMethod = resultingDescriptorName in OperatorConventions.NUMBER_CONVERSIONS
val isCharCode = argumentForReceiver.ctcType == CHAR && resultingDescriptorName == StandardNames.CHAR_CODE
val dontCreateILT = !isUnaryPlusMinus && !hasIntegerLiteralType(receiverExpression)
val dontCreateILT = defaultValueForDontCreateIntegerLiteralType &&
!isUnaryPlusMinus &&
!hasIntegerLiteralType(receiverExpression)
return createConstant(
result,
expectedType,
expectedType.takeUnless { dontCreateILT },
CompileTimeConstant.Parameters(
canBeUsedInAnnotation,
!isNumberConversionMethod && !isCharCode && isArgumentPure,
@@ -678,7 +682,7 @@ private class ConstantExpressionEvaluatorVisitor(
usesVariableAsConstant,
usesNonConstValAsConstant,
isConvertableConstVal = false,
dontCreateILT = defaultValueForDontCreateIntegerLiteralType && dontCreateILT
dontCreateILT = dontCreateILT
)
)
} else if (argumentsEntrySet.size == 1) {
@@ -713,6 +717,7 @@ private class ConstantExpressionEvaluatorVisitor(
usesVariableAsConstant(argumentForReceiver.expression) || usesVariableAsConstant(argumentForParameter.expression)
val usesNonConstValAsConstant =
usesNonConstValAsConstant(argumentForReceiver.expression) || usesNonConstValAsConstant(argumentForParameter.expression)
val dontCreateILT = defaultValueForDontCreateIntegerLiteralType && !hasIntegerLiteralType(receiverExpression)
val parameters = CompileTimeConstant.Parameters(
canBeUsedInAnnotation,
areArgumentsPure,
@@ -721,13 +726,17 @@ private class ConstantExpressionEvaluatorVisitor(
usesVariableAsConstant,
usesNonConstValAsConstant,
isConvertableConstVal = false,
dontCreateILT = defaultValueForDontCreateIntegerLiteralType && !hasIntegerLiteralType(receiverExpression)
dontCreateILT = dontCreateILT
)
return when (resultingDescriptorName) {
OperatorNameConventions.COMPARE_TO -> createCompileTimeConstantForCompareTo(result, callExpression)?.wrap(parameters)
OperatorNameConventions.EQUALS -> createCompileTimeConstantForEquals(result, callExpression)?.wrap(parameters)
else -> {
createConstant(result, expectedType, parameters)
createConstant(
result,
expectedType.takeUnless { dontCreateILT },
parameters
)
}
}
}
@@ -418,7 +418,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
DataFlowValue rightValue = components.dataFlowValueFactory.createDataFlowValue(right, rightType, context);
// We cannot say here anything new about rightValue except it has the same value as leftValue
resultInfo = resultInfo.replaceDataFlowInfo(dataFlowInfo.assign(leftValue, rightValue, components.languageVersionSettings));
NewSchemeOfIntegerOperatorResolutionChecker.checkArgument(expectedType, right, context.trace, components.moduleDescriptor);
NewSchemeOfIntegerOperatorResolutionChecker.checkArgument(expectedType, right, context.languageVersionSettings, context.trace, components.moduleDescriptor);
}
}
else {
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.DescriptorResolver
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.checkers.NewSchemeOfIntegerOperatorResolutionChecker
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
@@ -71,6 +72,13 @@ class ValueParameterResolver(
val defaultValue = parameter.defaultValue ?: return
val type = valueParameterDescriptor.type
expressionTypingServices.getTypeInfo(defaultValue, context.replaceExpectedType(type))
NewSchemeOfIntegerOperatorResolutionChecker.checkArgument(
type,
defaultValue,
context.languageVersionSettings,
context.trace,
constantExpressionEvaluator.module
)
if (DescriptorUtils.isAnnotationClass(DescriptorResolver.getContainingClass(context.scope))) {
val constant = constantExpressionEvaluator.evaluateExpression(defaultValue, context.trace, type)
if ((constant == null || constant.usesNonConstValAsConstant) && !type.isError) {
+1
View File
@@ -1,3 +1,4 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_BACKEND_FIR: JVM_IR
// For reasons this test is ignored, go to KT-46419
@@ -1,3 +1,4 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_BACKEND_FIR: JVM_IR
// For reasons this test is ignored, go to KT-46419
+1
View File
@@ -1,3 +1,4 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_BACKEND_FIR: JVM_IR
// For reasons this test is ignored, go to KT-46419
@@ -1,3 +1,4 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_BACKEND_FIR: JVM_IR
// For reasons this test is ignored, go to KT-46419
@@ -1,3 +1,4 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_BACKEND_FIR: JVM_IR
// For reasons this test is ignored, go to KT-46419
+1
View File
@@ -1,3 +1,4 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_BACKEND_FIR: JVM_IR
// For reasons this test is ignored, go to KT-46419
+1
View File
@@ -1,3 +1,4 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_BACKEND_FIR: JVM_IR
// For reasons this test is ignored, go to KT-46419
@@ -1,3 +1,4 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_BACKEND_FIR: JVM_IR
// For reasons this test is ignored, go to KT-46419
@@ -1,3 +1,4 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_BACKEND_FIR: JVM_IR
// For reasons this test is ignored, go to KT-46419
@@ -1,7 +1,7 @@
val p1: Int = 1 - 1
val p2: Long = 1 - 1
val p3: Byte = 1 - 1
val p4: Short = 1 - 1
val p2: Long = <!TYPE_MISMATCH!>1 - 1<!>
val p3: Byte = <!TYPE_MISMATCH!>1 - 1<!>
val p4: Short = <!TYPE_MISMATCH!>1 - 1<!>
val l1: Long = 1 - 1.toLong()
val l2: Byte = <!TYPE_MISMATCH!>1 - 1.toLong()<!>
@@ -21,4 +21,4 @@ val i4: Short = <!TYPE_MISMATCH!>1 - 1.toInt()<!>
val s1: Byte = <!TYPE_MISMATCH!>1 - 1.toShort()<!>
val s2: Int = 1 - 1.toShort()
val s3: Long = <!TYPE_MISMATCH!>1 - 1.toShort()<!>
val s4: Short = <!TYPE_MISMATCH!>1 - 1.toShort()<!>
val s4: Short = <!TYPE_MISMATCH!>1 - 1.toShort()<!>
@@ -13,9 +13,9 @@ public val l2: kotlin.Byte = 0.toLong()
public val l3: kotlin.Int = 0.toLong()
public val l4: kotlin.Short = 0.toLong()
public val p1: kotlin.Int = 0
public val p2: kotlin.Long = 0.toLong()
public val p3: kotlin.Byte = 0.toByte()
public val p4: kotlin.Short = 0.toShort()
public val p2: kotlin.Long = 0
public val p3: kotlin.Byte = 0
public val p4: kotlin.Short = 0
public val s1: kotlin.Byte = 0
public val s2: kotlin.Int = 0
public val s3: kotlin.Long = 0
@@ -1,12 +0,0 @@
val p1: Byte = <!TYPE_MISMATCH!>(1 + 2) * 2<!>
val p2: Short = <!TYPE_MISMATCH!>(1 + 2) * 2<!>
val p3: Int = (1 + 2) * 2
val p4: Long = <!TYPE_MISMATCH!>(1 + 2) * 2<!>
val b1: Byte = <!TYPE_MISMATCH!>(1.toByte() + 2) * 2<!>
val b2: Short = <!TYPE_MISMATCH!>(1.toShort() + 2) * 2<!>
val b3: Int = (1.toInt() + 2) * 2
val b4: Long = (1.toLong() + 2) * 2
val i1: Int = (1.toByte() + 2) * 2
val i2: Int = (1.toShort() + 2) * 2
@@ -1,7 +1,8 @@
val p1: Byte = (1 + 2) * 2
val p2: Short = (1 + 2) * 2
// FIR_IDENTICAL
val p1: Byte = <!TYPE_MISMATCH!>(1 + 2) * 2<!>
val p2: Short = <!TYPE_MISMATCH!>(1 + 2) * 2<!>
val p3: Int = (1 + 2) * 2
val p4: Long = (1 + 2) * 2
val p4: Long = <!TYPE_MISMATCH!>(1 + 2) * 2<!>
val b1: Byte = <!TYPE_MISMATCH!>(1.toByte() + 2) * 2<!>
val b2: Short = <!TYPE_MISMATCH!>(1.toShort() + 2) * 2<!>
@@ -9,4 +10,4 @@ val b3: Int = (1.toInt() + 2) * 2
val b4: Long = (1.toLong() + 2) * 2
val i1: Int = (1.toByte() + 2) * 2
val i2: Int = (1.toShort() + 2) * 2
val i2: Int = (1.toShort() + 2) * 2
@@ -6,7 +6,8 @@ public val b3: kotlin.Int = 6
public val b4: kotlin.Long = 6.toLong()
public val i1: kotlin.Int = 6
public val i2: kotlin.Int = 6
public val p1: kotlin.Byte = 6.toByte()
public val p2: kotlin.Short = 6.toShort()
public val p1: kotlin.Byte = 6
public val p2: kotlin.Short = 6
public val p3: kotlin.Int = 6
public val p4: kotlin.Long = 6.toLong()
public val p4: kotlin.Long = 6
@@ -0,0 +1,5 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
fun foo(ttlMillis: Long = <!TYPE_MISMATCH!>5 * 60 * 1000<!>) {}
const val cacheSize: Long = <!TYPE_MISMATCH!>4096 * 4<!>
@@ -0,0 +1,5 @@
// !LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
fun foo(ttlMillis: Long = <!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>5 * 60 * 1000<!>) {}
const val cacheSize: Long = <!INTEGER_OPERATOR_RESOLVE_WILL_CHANGE!>4096 * 4<!>
@@ -0,0 +1,5 @@
package
public const val cacheSize: kotlin.Long = 16384.toLong()
public fun foo(/*0*/ ttlMillis: kotlin.Long = ...): kotlin.Unit
@@ -0,0 +1,7 @@
// FIR_IDENTICAL
// LANGUAGE: +ApproximateIntegerLiteralTypesInReceiverPosition
fun foo(ttlMillis: Long = <!TYPE_MISMATCH!>5 * 60 * 1000<!>) {}
const val cacheSize: Long = <!TYPE_MISMATCH!>4096 * 4<!>
@@ -0,0 +1,4 @@
package
public const val cacheSize: kotlin.Long = 16384
public fun foo(/*0*/ ttlMillis: kotlin.Long = ...): kotlin.Unit
@@ -1,3 +1,4 @@
// LANGUAGE: -ApproximateIntegerLiteralTypesInReceiverPosition
// IGNORE_BACKEND_FIR: ANY
// For reasons this test is ignored, go to KT-46419
@@ -20263,6 +20263,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/numbers/kt47729_parenthesis.kt");
}
@Test
@TestMetadata("kt48361_disabled.kt")
public void testKt48361_disabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/numbers/kt48361_disabled.kt");
}
@Test
@TestMetadata("kt48361_enabled.kt")
public void testKt48361_enabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/numbers/kt48361_enabled.kt");
}
@Test
@TestMetadata("literalReceiverWithIntegerValueType.kt")
public void testLiteralReceiverWithIntegerValueType() throws Exception {
@@ -20257,6 +20257,18 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/numbers/kt47729_parenthesis.kt");
}
@Test
@TestMetadata("kt48361_disabled.kt")
public void testKt48361_disabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/numbers/kt48361_disabled.kt");
}
@Test
@TestMetadata("kt48361_enabled.kt")
public void testKt48361_enabled() throws Exception {
runTest("compiler/testData/diagnostics/tests/numbers/kt48361_enabled.kt");
}
@Test
@TestMetadata("literalReceiverWithIntegerValueType.kt")
public void testLiteralReceiverWithIntegerValueType() throws Exception {