From 97ef2de6e31d7dcc8c95e7a720ac2f5c8a3b9c8b Mon Sep 17 00:00:00 2001 From: "Anastasia.Nekrasova" Date: Wed, 22 Nov 2023 19:41:22 +0200 Subject: [PATCH] [K2] OPT_IN_USAGE_ERROR is absent when calling the enum primary constructor ^KT-63459 --- .../expression/FirOptInUsageAccessChecker.kt | 45 +++++++++++-------- .../experimental/constructorCheck.fir.kt | 5 +++ .../experimental/constructorCheck.kt | 5 +++ .../experimental/constructorCheck.txt | 22 +++++++++ 4 files changed, 58 insertions(+), 19 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageAccessChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageAccessChecker.kt index a3b5ae705b7..75490bfe94d 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageAccessChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirOptInUsageAccessChecker.kt @@ -11,12 +11,11 @@ import org.jetbrains.kotlin.fakeElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.isLhsOfAssignment import org.jetbrains.kotlin.fir.declarations.FirProperty -import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression -import org.jetbrains.kotlin.fir.expressions.FirStatement -import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment -import org.jetbrains.kotlin.fir.expressions.calleeReference +import org.jetbrains.kotlin.fir.declarations.utils.isFromEnumClass +import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol import org.jetbrains.kotlin.fir.resolve.fullyExpandedType +import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol import org.jetbrains.kotlin.fir.types.resolvedType object FirOptInUsageAccessChecker : FirBasicExpressionChecker() { @@ -31,22 +30,30 @@ object FirOptInUsageAccessChecker : FirBasicExpressionChecker() { val resolvedSymbol = expression.calleeReference?.toResolvedBaseSymbol() ?: return with(FirOptInUsageBaseChecker) { - if (expression is FirVariableAssignment) { - val experimentalities = resolvedSymbol.loadExperimentalities(context, fromSetter = true, null) + - loadExperimentalitiesFromTypeArguments(context, emptyList()) - reportNotAcceptedExperimentalities(experimentalities, expression.lValue, context, reporter) - } else if (expression is FirQualifiedAccessExpression) { - val dispatchReceiverType = expression.dispatchReceiver?.resolvedType?.fullyExpandedType(context.session) - - val experimentalities = resolvedSymbol.loadExperimentalities(context, fromSetter = false, dispatchReceiverType) + - loadExperimentalitiesFromTypeArguments(context, expression.typeArguments) - val source = if (expression.source?.kind == KtFakeSourceElementKind.DelegatedPropertyAccessor) { - val property = context.containingDeclarations.lastOrNull { it is FirProperty } as? FirProperty ?: return - property.delegate?.source?.fakeElement(KtFakeSourceElementKind.DelegatedPropertyAccessor) ?: return - } else { - expression.source + when { + expression is FirVariableAssignment -> { + val experimentalities = resolvedSymbol.loadExperimentalities(context, fromSetter = true, null) + + loadExperimentalitiesFromTypeArguments(context, emptyList()) + reportNotAcceptedExperimentalities(experimentalities, expression.lValue, context, reporter) + } + + expression is FirQualifiedAccessExpression -> { + val dispatchReceiverType = expression.dispatchReceiver?.resolvedType?.fullyExpandedType(context.session) + + val experimentalities = resolvedSymbol.loadExperimentalities(context, fromSetter = false, dispatchReceiverType) + + loadExperimentalitiesFromTypeArguments(context, expression.typeArguments) + val source = if (expression.source?.kind == KtFakeSourceElementKind.DelegatedPropertyAccessor) { + val property = context.containingDeclarations.lastOrNull { it is FirProperty } as? FirProperty ?: return + property.delegate?.source?.fakeElement(KtFakeSourceElementKind.DelegatedPropertyAccessor) ?: return + } else { + expression.source + } + reportNotAcceptedExperimentalities(experimentalities, expression, context, reporter, source) + } + expression is FirDelegatedConstructorCall && resolvedSymbol is FirConstructorSymbol && resolvedSymbol.isFromEnumClass -> { + val experimentalities = resolvedSymbol.loadExperimentalities(context, fromSetter = false, null) + reportNotAcceptedExperimentalities(experimentalities, expression.calleeReference, context, reporter) } - reportNotAcceptedExperimentalities(experimentalities, expression, context, reporter, source) } } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/constructorCheck.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/constructorCheck.fir.kt index bc88923e8b4..9c10a02158b 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/constructorCheck.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/constructorCheck.fir.kt @@ -15,6 +15,11 @@ class Other(val x: Int) { constructor(y: Long, some: Some? = null): this(some?.x ?: y.toInt()) } +enum class Enumeration @Marker constructor() { + ENTRY(), + ENTRY2; +} + fun foo(some: Some? = null) {} fun test() { diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/constructorCheck.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/constructorCheck.kt index 1e304744673..8d7ce25576d 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/constructorCheck.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/constructorCheck.kt @@ -15,6 +15,11 @@ class Other(val x: Int) { constructor(y: Long, some: Some? = null): this(some?.x ?: y.toInt()) } +enum class Enumeration @Marker constructor() { + ENTRY(), + ENTRY2; +} + fun foo(some: Some? = null) {} fun test() { diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/constructorCheck.txt b/compiler/testData/diagnostics/testsWithStdLib/experimental/constructorCheck.txt index 43c6eb8378c..9a755354e16 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/constructorCheck.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/constructorCheck.txt @@ -3,6 +3,28 @@ package public fun foo(/*0*/ some: Some? = ...): kotlin.Unit public fun test(): kotlin.Unit +public final enum class Enumeration : kotlin.Enum { + enum entry ENTRY + + enum entry ENTRY2 + + @Marker private constructor Enumeration() + @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: Enumeration): 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): Enumeration + public final /*synthesized*/ fun values(): kotlin.Array +} + @kotlin.RequiresOptIn public final annotation class Marker : kotlin.Annotation { public constructor Marker() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean