From 6c3aa6568e903143e0050e9ae6f061c561b6b727 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Thu, 21 Dec 2023 00:13:30 +0100 Subject: [PATCH] [FIR] Properly check constructor call in `FirConstCheckVisitor` --- .../expresssions/annotationWithReturn.kt | 2 +- .../fir/analysis/checkers/FirConstChecks.kt | 65 +++++++++---------- .../lambdaParameter.fir.kt | 4 +- .../tests/invalidTargetCrashesCompiler.fir.kt | 2 +- 4 files changed, 36 insertions(+), 37 deletions(-) diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/annotationWithReturn.kt b/compiler/fir/analysis-tests/testData/resolve/expresssions/annotationWithReturn.kt index 21f8a2cef26..efb6c1ab609 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/annotationWithReturn.kt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/annotationWithReturn.kt @@ -1,5 +1,5 @@ // Should be something like TYPE_MISMATCH here -@file:Some(return x) +@file:Some(return x) const val x = 42 diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConstChecks.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConstChecks.kt index 8e075a01626..cf545941c2f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConstChecks.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirConstChecks.kt @@ -44,36 +44,7 @@ internal fun checkConstantArguments( session: FirSession, ): ConstantArgumentKind { if (expression == null) return ConstantArgumentKind.VALID_CONST - - val firConstCheckVisitor = FirConstCheckVisitor(session) - - val expressionSymbol = expression.toReference()?.toResolvedCallableSymbol(discardErrorReference = true) - val classKindOfParent = with(firConstCheckVisitor) { - (expressionSymbol?.getReferencedClassSymbol() as? FirRegularClassSymbol)?.classKind - } - - fun FirExpression.getExpandedType() = resolvedType.fullyExpandedType(session) - - when { - expressionSymbol is FirConstructorSymbol && classKindOfParent == ClassKind.ANNOTATION_CLASS -> { - return ConstantArgumentKind.VALID_CONST - } - expressionSymbol == null -> { - return ConstantArgumentKind.VALID_CONST - } - expressionSymbol is FirConstructorSymbol -> { - if (expression is FirCallableReferenceAccess) return ConstantArgumentKind.VALID_CONST - if (expression.getExpandedType().isUnsignedType) { - (expression as FirFunctionCall).arguments.forEach { argumentExpression -> - checkConstantArguments(argumentExpression, session).ifNotValidConst { return it } - } - } else { - return ConstantArgumentKind.NOT_CONST - } - } - else -> return expression.accept(firConstCheckVisitor, null) - } - return ConstantArgumentKind.VALID_CONST + return expression.accept(FirConstCheckVisitor(session), null) } internal enum class ConstantArgumentKind { @@ -276,8 +247,14 @@ private class FirConstCheckVisitor(private val session: FirSession) : FirVisitor } if (calleeReference !is FirResolvedNamedReference) return ConstantArgumentKind.NOT_CONST - val symbol = calleeReference.resolvedSymbol as? FirNamedFunctionSymbol ?: return ConstantArgumentKind.NOT_CONST + return when (val symbol = calleeReference.resolvedSymbol) { + is FirNamedFunctionSymbol -> visitNamedFunction(functionCall, symbol) + is FirConstructorSymbol -> visitConstructorCall(functionCall, symbol) + else -> ConstantArgumentKind.NOT_CONST + } + } + private fun visitNamedFunction(functionCall: FirFunctionCall, symbol: FirNamedFunctionSymbol): ConstantArgumentKind { if (!symbol.canBeEvaluated() && !functionCall.isCompileTimeBuiltinCall()) { return ConstantArgumentKind.NOT_CONST } @@ -290,12 +267,26 @@ private class FirConstCheckVisitor(private val session: FirSession) : FirVisitor return ConstantArgumentKind.NOT_CONST } - exp.accept(this, data).ifNotValidConst { return it } + exp.accept(this, null).ifNotValidConst { return it } } return ConstantArgumentKind.VALID_CONST } + private fun visitConstructorCall(constructorCall: FirFunctionCall, symbol: FirConstructorSymbol): ConstantArgumentKind { + val classKindOfParent = (symbol.getReferencedClassSymbol() as? FirRegularClassSymbol)?.classKind + return when { + classKindOfParent == ClassKind.ANNOTATION_CLASS -> ConstantArgumentKind.VALID_CONST + constructorCall.getExpandedType().isUnsignedType -> { + constructorCall.arguments.forEach { argumentExpression -> + argumentExpression.accept(this, null).ifNotValidConst { return it } + } + ConstantArgumentKind.VALID_CONST + } + else -> ConstantArgumentKind.NOT_CONST + } + } + override fun visitQualifiedAccessExpression( qualifiedAccessExpression: FirQualifiedAccessExpression, data: Nothing? ): ConstantArgumentKind { @@ -307,6 +298,14 @@ private class FirConstCheckVisitor(private val session: FirSession) : FirVisitor return ConstantArgumentKind.VALID_CONST } + override fun visitResolvedQualifier(resolvedQualifier: FirResolvedQualifier, data: Nothing?): ConstantArgumentKind { + return ConstantArgumentKind.VALID_CONST + } + + override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: Nothing?): ConstantArgumentKind { + return visitQualifiedAccessExpression(callableReferenceAccess, data) + } + // --- Utils --- private fun FirBasedSymbol<*>.canBeEvaluated(): Boolean { return intrinsicConstEvaluation && this.hasAnnotation(StandardClassIds.Annotations.IntrinsicConstEvaluation, session) @@ -352,7 +351,7 @@ private class FirConstCheckVisitor(private val session: FirSession) : FirVisitor return this?.callableId?.packageName?.asString() == "kotlin" } - fun FirCallableSymbol<*>?.getReferencedClassSymbol(): FirBasedSymbol<*>? = + private fun FirCallableSymbol<*>?.getReferencedClassSymbol(): FirBasedSymbol<*>? = this?.resolvedReturnTypeRef ?.coneTypeSafe() ?.lookupTag diff --git a/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/lambdaParameter.fir.kt b/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/lambdaParameter.fir.kt index 3d515f5f47c..2cee654bbc6 100644 --- a/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/lambdaParameter.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/annotationParameterMustBeConstant/lambdaParameter.fir.kt @@ -3,14 +3,14 @@ @Target(AnnotationTarget.TYPE) annotation class Ann(val x: Int) -class A{ +class A{ fun local() = 1 var result = local() result += 1 result }) Any> -fun f(x: @Ann({ +fun f(x: @Ann({ fun local() = 1 var result = local() result += 1 diff --git a/compiler/testData/diagnostics/tests/invalidTargetCrashesCompiler.fir.kt b/compiler/testData/diagnostics/tests/invalidTargetCrashesCompiler.fir.kt index 9363350903c..86792ebf2df 100644 --- a/compiler/testData/diagnostics/tests/invalidTargetCrashesCompiler.fir.kt +++ b/compiler/testData/diagnostics/tests/invalidTargetCrashesCompiler.fir.kt @@ -1,5 +1,5 @@ // ISSUE: KT-59110 -@Target({}) +@Target({}) interface SomeInterface { }