From f5c59b1343ff1c21cfee958b46b29ef0526cadaf Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 21 Oct 2016 15:09:52 +0300 Subject: [PATCH] [NI] Report special error message on constant expression type mismatch. --- .../DiagnosticReporterByTrackingStrategy.kt | 19 +++++++++++++++++++ .../tower/KotlinToResolvedCallTransformer.kt | 10 +++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt index 00a8c2f6739..641a2506be5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -21,6 +21,8 @@ import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.* import org.jetbrains.kotlin.psi.Call +import org.jetbrains.kotlin.psi.KtConstantExpression +import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtPsiUtil import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingTrace @@ -32,9 +34,13 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy import org.jetbrains.kotlin.resolve.calls.tower.* +import org.jetbrains.kotlin.resolve.constants.CompileTimeConstantChecker +import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator +import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver class DiagnosticReporterByTrackingStrategy( + val constantExpressionEvaluator: ConstantExpressionEvaluator, val context: BasicCallResolutionContext, val trace: BindingTrace, val psiKotlinCall: PSIKotlinCall @@ -137,6 +143,7 @@ class DiagnosticReporterByTrackingStrategy( val constraintError = diagnostic as NewConstraintError (constraintError.position as? ArgumentConstraintPosition)?.let { val expression = it.argument.psiExpression ?: return + if (reportConstantTypeMismatch(constraintError, expression)) return trace.report(Errors.TYPE_MISMATCH.on(expression, constraintError.upperType, constraintError.lowerType)) } (constraintError.position as? ExplicitTypeParameterConstraintPosition)?.let { @@ -153,4 +160,16 @@ class DiagnosticReporterByTrackingStrategy( } } } + + private fun reportConstantTypeMismatch(constraintError: NewConstraintError, expression: KtExpression): Boolean { + if (expression is KtConstantExpression) { + val builtIns = context.scope.ownerDescriptor.builtIns + val constantValue = constantExpressionEvaluator.evaluateToConstantValue(expression, trace, context.expectedType) + val hasConstantTypeError = CompileTimeConstantChecker(context, builtIns, true) + .checkConstantExpressionType(constantValue, expression, constraintError.upperType) + if (hasConstantTypeError) return true + } + return false + } + } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index bc3b912c9bc..45884d144cb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -25,7 +25,9 @@ import org.jetbrains.kotlin.psi.KtPsiUtil import org.jetbrains.kotlin.psi.ValueArgument import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingTrace -import org.jetbrains.kotlin.resolve.calls.* +import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver +import org.jetbrains.kotlin.resolve.calls.DiagnosticReporterByTrackingStrategy +import org.jetbrains.kotlin.resolve.calls.REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType import org.jetbrains.kotlin.resolve.calls.callUtil.isFakeElement import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker @@ -36,6 +38,7 @@ import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind +import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils @@ -49,7 +52,8 @@ class KotlinToResolvedCallTransformer( private val callCheckers: Iterable, private val languageFeatureSettings: LanguageVersionSettings, private val dataFlowAnalyzer: DataFlowAnalyzer, - private val argumentTypeResolver: ArgumentTypeResolver + private val argumentTypeResolver: ArgumentTypeResolver, + private val constantExpressionEvaluator: ConstantExpressionEvaluator ) { fun transformAndReport( @@ -185,7 +189,7 @@ class KotlinToResolvedCallTransformer( reported = true } } - val diagnosticReporter = DiagnosticReporterByTrackingStrategy(context, reportTrackedTrace, completedCall.kotlinCall.psiKotlinCall) + val diagnosticReporter = DiagnosticReporterByTrackingStrategy(constantExpressionEvaluator, context, reportTrackedTrace, completedCall.kotlinCall.psiKotlinCall) for (diagnostic in completedCall.resolutionStatus.diagnostics) { reported = false