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 7910b0d4ca3..b8cacd6ea62 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 @@ -90,7 +90,7 @@ internal fun checkConstantArguments( if (coneType is ConeErrorType) return ConstantArgumentKind.NOT_CONST - while (coneType?.classId == StandardClassIds.Array) + while (coneType?.fullyExpandedClassId(session) == StandardClassIds.Array) coneType = (coneType.lowerBoundIfFlexible().typeArguments.first() as? ConeKotlinTypeProjection)?.type ?: break return when { @@ -122,7 +122,7 @@ internal fun checkConstantArguments( if (calleeReference is FirErrorNamedReference) { return null } - if (expression.resolvedType.classId == StandardClassIds.KClass) { + if (expression.resolvedType.fullyExpandedClassId(session) == StandardClassIds.KClass) { return ConstantArgumentKind.NOT_KCLASS_LITERAL } @@ -134,13 +134,13 @@ internal fun checkConstantArguments( if (calleeReference !is FirResolvedNamedReference) return ConstantArgumentKind.NOT_CONST val symbol = calleeReference.resolvedSymbol as? FirNamedFunctionSymbol ?: return ConstantArgumentKind.NOT_CONST - if (!symbol.canBeEvaluated() && !expression.isCompileTimeBuiltinCall() || expression.isForbiddenComplexConstant(session)) { + if (!symbol.canBeEvaluated() && !expression.isCompileTimeBuiltinCall(session) || expression.isForbiddenComplexConstant(session)) { return ConstantArgumentKind.NOT_CONST } for (exp in expression.arguments.plus(expression.dispatchReceiver).plus(expression.extensionReceiver)) { if (exp == null) continue - val expClassId = exp.resolvedType.lowerBoundIfFlexible().classId + val expClassId = exp.resolvedType.fullyExpandedClassId(session) // TODO, KT-59823: add annotation for allowed constant types if (expClassId !in StandardClassIds.constantAllowedTypes) { return ConstantArgumentKind.NOT_CONST @@ -165,12 +165,12 @@ internal fun checkConstantArguments( @OptIn(SymbolInternals::class) val property = propertySymbol.fir when { - property.unwrapFakeOverrides().symbol.canBeEvaluated() || property.isCompileTimeBuiltinProperty() -> { + property.unwrapFakeOverrides().symbol.canBeEvaluated() || property.isCompileTimeBuiltinProperty(session) -> { val receiver = listOf(expression.dispatchReceiver, expression.extensionReceiver).single { it != null }!! return checkConstantArguments(receiver, session) } propertySymbol.isLocal || propertySymbol.callableId.className?.isRoot == false -> return ConstantArgumentKind.NOT_CONST - expressionType.classId == StandardClassIds.KClass -> return ConstantArgumentKind.NOT_KCLASS_LITERAL + expressionType.fullyExpandedClassId(session) == StandardClassIds.KClass -> return ConstantArgumentKind.NOT_KCLASS_LITERAL //TODO, KT-59822: UNRESOLVED REFERENCE expression.dispatchReceiver is FirThisReceiverExpression -> return null @@ -229,7 +229,7 @@ private val compileTimeConversionFunctions = listOf( "toInt", "toLong", "toShort", "toByte", "toFloat", "toDouble", "toChar", "toBoolean" ).mapTo(hashSetOf()) { Name.identifier(it) } -private fun FirFunctionCall.isCompileTimeBuiltinCall(): Boolean { +private fun FirFunctionCall.isCompileTimeBuiltinCall(session: FirSession): Boolean { val calleeReference = this.calleeReference if (calleeReference !is FirResolvedNamedReference) return false @@ -238,7 +238,7 @@ private fun FirFunctionCall.isCompileTimeBuiltinCall(): Boolean { if (!symbol.fromKotlin()) return false val coneType = this.dispatchReceiver?.resolvedType - val receiverClassId = coneType?.lowerBoundIfFlexible()?.classId + val receiverClassId = coneType?.fullyExpandedClassId(session) if (receiverClassId in StandardClassIds.unsignedTypes) return false @@ -254,9 +254,9 @@ private fun FirFunctionCall.isCompileTimeBuiltinCall(): Boolean { return false } -private fun FirProperty.isCompileTimeBuiltinProperty(): Boolean { +private fun FirProperty.isCompileTimeBuiltinProperty(session: FirSession): Boolean { val receiverType = dispatchReceiverType ?: receiverParameter?.typeRef?.coneTypeSafe() ?: return false - val receiverClassId = receiverType.lowerBoundIfFlexible().classId ?: return false + val receiverClassId = receiverType.fullyExpandedClassId(session) ?: return false return when (name.asString()) { "length" -> receiverClassId == StandardClassIds.String "code" -> receiverClassId == StandardClassIds.Char diff --git a/compiler/testData/diagnostics/tests/modifiers/const/applicability.fir.kt b/compiler/testData/diagnostics/tests/modifiers/const/applicability.fir.kt index a60ec2adcb9..547a319a666 100644 --- a/compiler/testData/diagnostics/tests/modifiers/const/applicability.fir.kt +++ b/compiler/testData/diagnostics/tests/modifiers/const/applicability.fir.kt @@ -100,6 +100,10 @@ const val constInitializer12 = (-1.0) % 0 const val constInitializer13 = 1.0.rem(0) const val constInitializer15 = 1.0.div(0) +typealias IntAlias = Int +const val constInitializer16: IntAlias = 1 +const val constInitializer17 = constInitializer16 + 0 + // ------------------ class Delegate { operator fun getValue(thisRef: Any?, prop: KProperty<*>): Int = 1 diff --git a/compiler/testData/diagnostics/tests/modifiers/const/applicability.kt b/compiler/testData/diagnostics/tests/modifiers/const/applicability.kt index 6b53b8d7874..3ad65790993 100644 --- a/compiler/testData/diagnostics/tests/modifiers/const/applicability.kt +++ b/compiler/testData/diagnostics/tests/modifiers/const/applicability.kt @@ -100,6 +100,10 @@ const val constInitializer12 = (-1.0) % 0 const val constInitializer13 = 1.0.rem(0) const val constInitializer15 = 1.0.div(0) +typealias IntAlias = Int +const val constInitializer16: IntAlias = 1 +const val constInitializer17 = constInitializer16 + 0 + // ------------------ class Delegate { operator fun getValue(thisRef: Any?, prop: KProperty<*>): Int = 1 diff --git a/compiler/testData/diagnostics/tests/modifiers/const/applicability.txt b/compiler/testData/diagnostics/tests/modifiers/const/applicability.txt deleted file mode 100644 index 71d124ab7dc..00000000000 --- a/compiler/testData/diagnostics/tests/modifiers/const/applicability.txt +++ /dev/null @@ -1,136 +0,0 @@ -package - -public const val constInitializer1: kotlin.Double = Infinity.toDouble() -public const val constInitializer10: kotlin.Double = NaN.toDouble() -public const val constInitializer11: kotlin.Double = NaN.toDouble() -public const val constInitializer12: kotlin.Double = NaN.toDouble() -public const val constInitializer13: kotlin.Double = NaN.toDouble() -public const val constInitializer15: kotlin.Double = Infinity.toDouble() -public const val constInitializer2: kotlin.Double = Infinity.toDouble() -public const val constInitializer3: kotlin.Double = Infinity.toDouble() -public const val constInitializer4: kotlin.Double = -Infinity.toDouble() -public const val constInitializer5: kotlin.Double = NaN.toDouble() -public const val constInitializer6: kotlin.Double = Infinity.toDouble() -public const val constInitializer7: kotlin.Double = -Infinity.toDouble() -public const val constInitializer8: kotlin.Double = NaN.toDouble() -public const val constInitializer9: kotlin.Double = NaN.toDouble() -public const val defaultGetter: kotlin.Int = 19 -public const val delegated: kotlin.Int -public const val nonConstInitializer1: kotlin.Int -public const val nonConstInitializer10: kotlin.Int -public const val nonConstInitializer11: kotlin.Int -public const val nonConstInitializer12: kotlin.Int -public const val nonConstInitializer14: kotlin.Int -public const val nonConstInitializer15: kotlin.Int -public const val nonConstInitializer2: kotlin.String -public const val nonConstInitializer3: kotlin.String -public const val nonConstInitializer4: kotlin.Double -public const val nonConstInitializer5: kotlin.Int -public const val nonConstInitializer6: kotlin.Int -public const val nonConstInitializer7: kotlin.Int -public const val nonConstInitializer8: kotlin.Int -public const val nonConstInitializer9: kotlin.Double -private val privateTopLevel: kotlin.Int = 3 -public const var topLeveLVar: kotlin.Int -public const val topLevel: kotlin.Int = 0 -public const val topLevelInferred: kotlin.Int = 1 -public const val withExplicitDefaultGetter: kotlin.Int = 1 -public const val withGetter: kotlin.Int -public fun foo(): kotlin.Int - -public object A { - private constructor A() - public const final val inObject: kotlin.Int = 4 - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String -} - -public final class B { - public constructor B(/*0*/ constructor: kotlin.Int = ...) - public final val constructor: kotlin.Int - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String -} - -public abstract class C { - public constructor C() - public const open val x: kotlin.Int = 6 - public const abstract val y: kotlin.Int = 7 - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - - public companion object Companion { - private constructor Companion() - public const final val inCompaionObject: kotlin.Int = 8 - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - } -} - -public object D : C { - private constructor D() - public const final val final: kotlin.Int = 11 - public const final val inObject: kotlin.Int = 10 - public const final val withoutInitializer: kotlin.Int - public const open override /*1*/ val x: kotlin.Int = 9 - public const abstract override /*1*/ /*fake_override*/ val y: kotlin.Int = 7 - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String -} - -public final class Delegate { - public constructor Delegate() - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public final operator fun getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>): kotlin.Int - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ prop: kotlin.reflect.KProperty<*>, /*2*/ value: kotlin.Int): kotlin.Unit - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String -} - -public final enum class MyEnum : kotlin.Enum { - enum entry A - - private constructor MyEnum() - public const final val inEnum: kotlin.Int = 17 - @kotlin.internal.IntrinsicConstEvaluation public final override /*1*/ /*fake_override*/ val name: kotlin.String - public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int - protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any - public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int - public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit - public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! - public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - - // Static members - public final /*synthesized*/ val entries: kotlin.enums.EnumEntries - public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): MyEnum - public final /*synthesized*/ fun values(): kotlin.Array -} - -public final class Outer { - public constructor Outer() - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - - public final inner class Inner { - public constructor Inner() - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - - public object C { - private constructor C() - public const final val a: kotlin.Int = 18 - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String - } - } -}