[K2] Report NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION when it is appropriate

This commit is contained in:
Ivan Kylchik
2023-12-05 17:19:25 +01:00
committed by Space Team
parent 0d127f6daf
commit 8cd9479f20
13 changed files with 23 additions and 56 deletions
@@ -21,8 +21,8 @@ const val l = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>k<!>
const val m = "123".toString()
const val n = "456".length
val o = "789"
const val p = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>o.toString()<!>
const val q = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>o.length<!>
const val p = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>o.toString()<!>
const val q = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>o.length<!>
class ForConst{
companion object {
@@ -5,7 +5,7 @@ FILE: withSuppression.kt
}
public final val y: R|kotlin/String| = String(789)
public get(): R|kotlin/String|
public final const val z: R|kotlin/String| = @R|kotlin/Suppress|(names = vararg(String(CONST_VAL_WITH_NON_CONST_INITIALIZER))) R|/y|
public final const val z: R|kotlin/String| = @R|kotlin/Suppress|(names = vararg(String(NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION))) R|/y|
public get(): R|kotlin/String|
@R|kotlin/annotation/Target|(allowedTargets = vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.TYPE|)) public final annotation class Ann : R|kotlin/Annotation| {
public constructor(): R|Ann| {
@@ -4,7 +4,7 @@ const val x = "123"
val y = "789"
const val z = @Suppress(<!ERROR_SUPPRESSION!>"CONST_VAL_WITH_NON_CONST_INITIALIZER"<!>) y
const val z = @Suppress(<!ERROR_SUPPRESSION!>"NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION"<!>) y
@Target(AnnotationTarget.TYPE)
annotation class Ann
@@ -7,16 +7,17 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.analysis.checkers.canBeUsedForConstVal
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.getModifier
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.checkers.canBeEvaluatedAtCompileTime
import org.jetbrains.kotlin.fir.analysis.checkers.*
import org.jetbrains.kotlin.fir.analysis.checkers.ConstantArgumentKind
import org.jetbrains.kotlin.fir.analysis.checkers.checkConstantArguments
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.utils.isConst
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.coneType
@@ -62,8 +63,11 @@ object FirConstPropertyChecker : FirPropertyChecker() {
return
}
if (!canBeEvaluatedAtCompileTime(initializer, context.session)) {
reporter.reportOn(initializer.source, FirErrors.CONST_VAL_WITH_NON_CONST_INITIALIZER, context)
val errorKind = when (checkConstantArguments(initializer, context.session)) {
null -> return
ConstantArgumentKind.NOT_CONST_VAL_IN_CONST_EXPRESSION -> FirErrors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION
else -> FirErrors.CONST_VAL_WITH_NON_CONST_INITIALIZER
}
reporter.reportOn(initializer.source, errorKind, context)
}
}
@@ -2,11 +2,11 @@ val nonConstBool = true
const val constBool = false
const val andExpr1 = true && false
const val andExpr2 = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>nonConstBool && false<!>
const val andExpr2 = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>nonConstBool && false<!>
const val andExpr3 = true && constBool
const val andExpr4 = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>nonConstBool && constBool<!>
const val andExpr4 = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>nonConstBool && constBool<!>
const val orExpr1 = true || false
const val orExpr2 = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>nonConstBool || false<!>
const val orExpr2 = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>nonConstBool || false<!>
const val orExpr3 = true || constBool
const val orExpr4 = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>nonConstBool || constBool<!>
const val orExpr4 = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>nonConstBool || constBool<!>
@@ -4,5 +4,5 @@ val nonConstBool = true
const val constBool = false
const val s1 = """ ${ true && false } """
const val s2 = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>""" ${ nonConstBool && false } """<!>
const val s2 = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>""" ${ nonConstBool && false } """<!>
const val s3 = """ ${ constBool && false } """
@@ -1,8 +0,0 @@
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
val nonConstBool = true
const val constBool = false
const val s1 = """ ${ true && false } """
const val s2 = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>""" ${ nonConstBool && false } """<!>
const val s3 = """ ${ constBool && false } """
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// LANGUAGE: -ProhibitSimplificationOfNonTrivialConstBooleanExpressions
val nonConstBool = true
@@ -20,5 +20,5 @@ const val withWhen3 = when(value) {
const val multibranchIf = if (value == 100) 1 else if (value == 1000) 2 else 3
val nonConstFlag = true
const val errorConstIf = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>if (nonConstFlag) 1 else 2<!>
const val errorBranch = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>if (flag) nonConstFlag else false<!>
const val errorConstIf = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>if (nonConstFlag) 1 else 2<!>
const val errorBranch = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>if (flag) nonConstFlag else false<!>
@@ -1,16 +0,0 @@
const val simple = "O${'K'} ${1.toLong() + 2.0}"
const val withInnerConcatenation = "1 ${"2 ${3} ${4} 5"} 6"
object A
object B {
override fun toString(): String = "B"
}
const val printA = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>"A: $A"<!>
const val printB = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>"B: $B"<!>
const val withNull = "1 ${null}"
const val withNullPlus = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>"1" + null<!>
val nonConst = 0
const val withNonConst = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>"A $nonConst B"<!>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
const val simple = "O${'K'} ${1.toLong() + 2.0}"
const val withInnerConcatenation = "1 ${"2 ${3} ${4} 5"} 6"
@@ -1,16 +0,0 @@
val nonConst = 1
const val constConst = <!CONST_VAL_WITH_NON_CONST_INITIALIZER!>nonConst * nonConst + 2<!>
annotation class Ann(val x: Int, val y: String)
@Ann(<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>nonConst<!>, <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>"${nonConst}"<!>)
fun foo1() {}
@Ann(<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>nonConst + constConst<!>, "${constConst}")
fun foo2() {}
annotation class ArrayAnn(val x: IntArray)
@ArrayAnn(<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>intArrayOf(1, constConst, <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>nonConst<!>)<!>)
fun foo3() {}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
val nonConst = 1
const val constConst = <!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>nonConst * nonConst + 2<!>