From d7eb67a436cd48a3d9503fc08c656253f41843ed Mon Sep 17 00:00:00 2001 From: Tomas Husak Date: Wed, 29 Nov 2023 16:52:01 +0100 Subject: [PATCH] [FIR] KT-59368 context receiver subtyping checker --- .../diagnostics/KtFirDataClassConverters.kt | 6 + .../api/fir/diagnostics/KtFirDiagnostics.kt | 4 + .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 5 + .../contextReceiversSubtyping.fir.txt | 27 +++ .../checkers/contextReceiversSubtyping.kt | 19 ++ .../FirLightTreeDiagnosticsTestGenerated.java | 6 + .../FirPsiDiagnosticTestGenerated.java | 6 + .../diagnostics/FirDiagnosticsList.kt | 1 + .../fir/analysis/diagnostics/FirErrors.kt | 1 + .../FirNonSuppressibleErrorNames.kt | 1 + .../fir/analysis/checkers/SourceHelpers.kt | 23 ++ .../FirContextReceiversDeclarationChecker.kt | 86 ++++--- .../type/FirContextReceiversTypeChecker.kt | 33 ++- .../diagnostics/FirErrorsDefaultMessages.kt | 5 + .../subtypingBetweenContextReceivers.fir.kt | 221 ------------------ .../subtypingBetweenContextReceivers.kt | 1 + .../contextReceivers/unsupported.fir.kt | 4 +- 17 files changed, 181 insertions(+), 268 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolve/checkers/contextReceiversSubtyping.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolve/checkers/contextReceiversSubtyping.kt delete mode 100644 compiler/testData/diagnostics/tests/extensions/contextReceivers/subtypingBetweenContextReceivers.fir.kt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index e66a2e84058..d62f08a2619 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -2105,6 +2105,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.SUBTYPING_BETWEEN_CONTEXT_RECEIVERS) { firDiagnostic -> + SubtypingBetweenContextReceiversImpl( + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirErrors.RECURSION_IN_IMPLICIT_TYPES) { firDiagnostic -> RecursionInImplicitTypesImpl( firDiagnostic as KtPsiDiagnostic, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 6f944ae230d..a64d43f7c07 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -1500,6 +1500,10 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = UnsupportedContextualDeclarationCall::class } + interface SubtypingBetweenContextReceivers : KtFirDiagnostic { + override val diagnosticClass get() = SubtypingBetweenContextReceivers::class + } + interface RecursionInImplicitTypes : KtFirDiagnostic { override val diagnosticClass get() = RecursionInImplicitTypes::class } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index 674cf3042df..f90301ca61f 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -1800,6 +1800,11 @@ internal class UnsupportedContextualDeclarationCallImpl( token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.UnsupportedContextualDeclarationCall +internal class SubtypingBetweenContextReceiversImpl( + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.SubtypingBetweenContextReceivers + internal class RecursionInImplicitTypesImpl( firDiagnostic: KtPsiDiagnostic, token: KtLifetimeToken, diff --git a/compiler/fir/analysis-tests/testData/resolve/checkers/contextReceiversSubtyping.fir.txt b/compiler/fir/analysis-tests/testData/resolve/checkers/contextReceiversSubtyping.fir.txt new file mode 100644 index 00000000000..c7aefe5efe8 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/checkers/contextReceiversSubtyping.fir.txt @@ -0,0 +1,27 @@ +FILE: contextReceiversSubtyping.kt + public abstract interface D : R|D1|, R|D2| { + } + public abstract interface D1 : R|kotlin/Any| { + } + public abstract interface D2 : R|kotlin/Any| { + } + context(R|T|, R|D2|) + public final fun foo(): R|kotlin/Unit| { + } + public abstract interface Cov : R|kotlin/Any| { + } + public final class A : R|kotlin/Any| { + public constructor(): R|A| { + super() + } + + } + public final class B : R|kotlin/Any| { + public constructor(): R|B| { + super() + } + + } + context(R|Cov|, R|Cov|) + public final fun foo(): R|kotlin/Unit| { + } diff --git a/compiler/fir/analysis-tests/testData/resolve/checkers/contextReceiversSubtyping.kt b/compiler/fir/analysis-tests/testData/resolve/checkers/contextReceiversSubtyping.kt new file mode 100644 index 00000000000..5d6cc09892f --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/checkers/contextReceiversSubtyping.kt @@ -0,0 +1,19 @@ +// FIR_IDENTICAL +// !LANGUAGE: +ContextReceivers + +interface D: D1, D2 {} +interface D1 {} +interface D2 {} + +context(T, D2) +fun foo() where T: D1, T: D2 {} + +interface Cov {} +class A {} +class B {} + +// This sholdn't be an error since the type parameter is predetermined to be `A`, +// which causes that there can't be subtyping between the context receivers. +// However, the cheking is simplified because it is time-consuming process. +context(Cov, Cov) +fun A> foo() {} diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java index d5023801a1a..61f99dc0f49 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeDiagnosticsTestGenerated.java @@ -1503,6 +1503,12 @@ public class FirLightTreeDiagnosticsTestGenerated extends AbstractFirLightTreeDi runTest("compiler/fir/analysis-tests/testData/resolve/checkers/complexConflictingProjections.kt"); } + @Test + @TestMetadata("contextReceiversSubtyping.kt") + public void testContextReceiversSubtyping() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/checkers/contextReceiversSubtyping.kt"); + } + @Test @TestMetadata("importAnnotationWithRequiresOptIn.kt") public void testImportAnnotationWithRequiresOptIn() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java index d7f5f6dc9a8..2f859e0e790 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiDiagnosticTestGenerated.java @@ -1503,6 +1503,12 @@ public class FirPsiDiagnosticTestGenerated extends AbstractFirPsiDiagnosticTest runTest("compiler/fir/analysis-tests/testData/resolve/checkers/complexConflictingProjections.kt"); } + @Test + @TestMetadata("contextReceiversSubtyping.kt") + public void testContextReceiversSubtyping() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/checkers/contextReceiversSubtyping.kt"); + } + @Test @TestMetadata("importAnnotationWithRequiresOptIn.kt") public void testImportAnnotationWithRequiresOptIn() throws Exception { diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 3e55fd62a8b..6fd2d40e1a7 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -676,6 +676,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { } val AMBIGUOUS_CALL_WITH_IMPLICIT_CONTEXT_RECEIVER by error(PositioningStrategy.REFERENCE_BY_QUALIFIED) val UNSUPPORTED_CONTEXTUAL_DECLARATION_CALL by error(PositioningStrategy.NAME_IDENTIFIER) + val SUBTYPING_BETWEEN_CONTEXT_RECEIVERS by error(PositioningStrategy.DEFAULT) } val TYPES_AND_TYPE_PARAMETERS by object : DiagnosticGroup("Types & type parameters") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index c079073acce..7c3347dcded 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -415,6 +415,7 @@ object FirErrors { val MULTIPLE_ARGUMENTS_APPLICABLE_FOR_CONTEXT_RECEIVER by error1(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val AMBIGUOUS_CALL_WITH_IMPLICIT_CONTEXT_RECEIVER by error0(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val UNSUPPORTED_CONTEXTUAL_DECLARATION_CALL by error0(SourceElementPositioningStrategies.NAME_IDENTIFIER) + val SUBTYPING_BETWEEN_CONTEXT_RECEIVERS by error0() // Types & type parameters val RECURSION_IN_IMPLICIT_TYPES by error0() diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirNonSuppressibleErrorNames.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirNonSuppressibleErrorNames.kt index 8403a1b2112..48bbe0dc034 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirNonSuppressibleErrorNames.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirNonSuppressibleErrorNames.kt @@ -263,6 +263,7 @@ val FIR_NON_SUPPRESSIBLE_ERROR_NAMES: Set = setOf( "MULTIPLE_ARGUMENTS_APPLICABLE_FOR_CONTEXT_RECEIVER", "AMBIGUOUS_CALL_WITH_IMPLICIT_CONTEXT_RECEIVER", "UNSUPPORTED_CONTEXTUAL_DECLARATION_CALL", + "SUBTYPING_BETWEEN_CONTEXT_RECEIVERS", "RECURSION_IN_IMPLICIT_TYPES", "INFERENCE_ERROR", "PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT", diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/SourceHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/SourceHelpers.kt index 2714a933c28..8b9f9abbd19 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/SourceHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/SourceHelpers.kt @@ -5,10 +5,19 @@ package org.jetbrains.kotlin.fir.analysis.checkers +import com.intellij.lang.LighterASTNode +import org.jetbrains.kotlin.KtLightSourceElement +import org.jetbrains.kotlin.KtNodeTypes +import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.diagnostics.findChildByType +import org.jetbrains.kotlin.diagnostics.findDescendantByType +import org.jetbrains.kotlin.diagnostics.traverseDescendants import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.toKtLightSourceElement +import org.jetbrains.kotlin.util.getChildren /** @@ -23,3 +32,17 @@ fun KtModifierKeywordToken.toVisibilityOrNull(): Visibility? { else -> null } } + +/** + * Locates first [CONTEXT_RECEIVER_LIST] and returns position in source. + */ +fun KtSourceElement.findContextReceiverListSource(): KtLightSourceElement? { + if (this.lighterASTNode.tokenType == KtNodeTypes.CONTEXT_RECEIVER_LIST) + return this.lighterASTNode.toKtLightSourceElement(treeStructure) + + return treeStructure.findDescendantByType( + lighterASTNode, + KtNodeTypes.CONTEXT_RECEIVER_LIST, + false + )?.toKtLightSourceElement(treeStructure) +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirContextReceiversDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirContextReceiversDeclarationChecker.kt index a8b0f39058e..0c38266095f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirContextReceiversDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirContextReceiversDeclarationChecker.kt @@ -5,27 +5,34 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration -import com.intellij.lang.LighterASTNode import org.jetbrains.kotlin.KtFakeSourceElementKind -import org.jetbrains.kotlin.KtLightSourceElement -import org.jetbrains.kotlin.KtNodeTypes.CONTEXT_RECEIVER_LIST -import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.findContextReceiverListSource import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.toKtLightSourceElement -import org.jetbrains.kotlin.util.getChildren +import org.jetbrains.kotlin.fir.types.* object FirContextReceiversDeclarationChecker : FirBasicDeclarationChecker() { override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { - if (context.languageVersionSettings.supportsFeature(LanguageFeature.ContextReceivers)) return if (declaration.source?.kind is KtFakeSourceElementKind) return - if (!declaration.hasContextReceiver()) return + val contextReceivers = declaration.getContextReceiver() + if (contextReceivers.isEmpty()) return val source = declaration.source?.findContextReceiverListSource() ?: return + if (context.languageVersionSettings.supportsFeature(LanguageFeature.ContextReceivers)) { + if (checkSubTypes(contextReceivers.map { it.typeRef.coneType }, context)) { + reporter.reportOn( + source, + FirErrors.SUBTYPING_BETWEEN_CONTEXT_RECEIVERS, + context + ) + } + return + } + reporter.reportOn( source, FirErrors.UNSUPPORTED_FEATURE, @@ -34,36 +41,47 @@ object FirContextReceiversDeclarationChecker : FirBasicDeclarationChecker() { ) } - private fun FirDeclaration.hasContextReceiver(): Boolean { - val contextReceivers = when (this) { + private fun FirDeclaration.getContextReceiver(): List { + return when (this) { is FirCallableDeclaration -> contextReceivers is FirRegularClass -> contextReceivers is FirScript -> contextReceivers else -> emptyList() } - return contextReceivers.isNotEmpty() - } - - - private fun KtSourceElement.findContextReceiverListSource(): KtLightSourceElement? { - var contextReceiverList: LighterASTNode? = null - var contextReceiverListOffset = startOffset - - val nodes = lighterASTNode.getChildren(treeStructure) - for (node in nodes) { - if (node.tokenType == CONTEXT_RECEIVER_LIST) { - contextReceiverList = node - break - } else { - contextReceiverListOffset += node.endOffset - node.startOffset - } - } - if (contextReceiverList == null) return null - - return contextReceiverList.toKtLightSourceElement( - treeStructure, - startOffset = contextReceiverListOffset, - endOffset = contextReceiverListOffset + contextReceiverList.textLength, - ) } } + +/** + * Simplified checking of subtype relation used in context receiver checkers. + * It converts type parameters to star projections and top level type parameters to its supertypes. Then it checks the relation. + */ +fun checkSubTypes(types: List, context: CheckerContext): Boolean { + fun replaceTypeParametersByStarProjections(type: ConeClassLikeType): ConeClassLikeType { + return type.withArguments(type.typeArguments.map { + when { + it.isStarProjection -> it + it.type!! is ConeTypeParameterType -> ConeStarProjection + it.type!! is ConeClassLikeType -> replaceTypeParametersByStarProjections(it.type as ConeClassLikeType) + else -> it + } + }.toTypedArray()) + } + + val replacedTypeParameters = types.flatMap { r -> + when (r) { + is ConeTypeParameterType -> r.lookupTag.typeParameterSymbol.resolvedBounds.map { it.type } + is ConeClassLikeType -> listOf(replaceTypeParametersByStarProjections(r)) + else -> listOf(r) + } + } + + for (i in replacedTypeParameters.indices) + for (j in i + 1.. -interface Cov - -// Functions - -context(A, A) -fun f1() {} - -context(A, B) -fun f2() {} - -context(A, C) -fun f3() {} - -context(B, C) -fun f4() {} - -context(C, C) -fun f5() {} - -context(A, A, A) -fun f6() {} - -context(Inv, Inv) -fun f7() {} - -context(Inv, Inv) -fun f8() {} - -context(Inv, Inv) -fun f9() {} - -context(Cov, Cov) -fun f10() {} - -context(Cov, Cov) -fun f11() {} - -context(T, A) -fun f12() {} - -// Classes - -context(A, A) -class C1 { - context(A, A) - val p: Any get() = 42 - - context(A, A) - fun m() {} -} - -context(A, B) -class C2 { - context(A, B) - val p: Any get() = 42 - - context(A, B) - fun m() {} -} - -context(A, C) -class C3 { - context(A, C) - val p: Any get() = 42 - - context(A, C) - fun m() {} -} - -context(B, C) -class C4 { - context(B, C) - val p: Any get() = 42 - - context(B, C) - fun m() {} -} - -context(C, C) -class C5 { - context(C, C) - val p: Any get() = 42 - - context(C, C) - fun m() {} -} - -context(A, A, A) -class C6 { - context(A, A, A) - val p: Any get() = 42 - - context(A, A, A) - fun m() {} -} - -context(Inv, Inv) -class C7 { - context(Inv, Inv) - val p: Any get() = 42 - - context(Inv, Inv) - fun m() {} -} - -context(Inv, Inv) -class C8 { - context(Inv, Inv) - val p: Any get() = 42 - - context(Inv, Inv) - fun m() {} -} - -context(Inv, Inv) -class C9 { - context(Inv, Inv) - val p: Any get() = 42 - - context(Inv, Inv) - fun m() {} -} - -context(Cov, Cov) -class C10 { - context(Cov, Cov) - val p: Any get() = 42 - - context(Cov, Cov) - fun m() {} -} - -context(Cov, Cov) -class C11 { - context(Cov, Cov) - val p: Any get() = 42 - - context(Cov, Cov) - fun m() {} -} - -context(T, A) -class C12 { - context(T, A) - val p: Any get() = 42 - - context(T, A) - fun m() {} -} - -// Properties - -context(A, A) -val p1: Any? - get() { return null } - -context(A, B) -val p2: Any? - get() { return null } - -context(A, C) -val p3: Any? - get() { return null } - -context(B, C) -val p4: Any? - get() { return null } - -context(C, C) -val p5: Any? - get() { return null } - -context(A, A, A) -val p6: Any? - get() { return null } - -context(Inv, Inv) -val p7: Any? - get() { return null } - -context(Inv, Inv) -val p8: Any? - get() { return null } - -context(Inv, Inv) -val p9: Any? - get() { return null } - -context(Cov, Cov) -val p10: Any? - get() { return null } - -context(Cov, Cov) -val p11: Any? - get() { return null } - -context(T, A) -val p12: Any? - get() { return null } - -// Function types - -// Function types are processed with the same function that is used for checking contextual declarations -// So we check here only one simple case: `context(A, B)` - -context(A, B) -fun f(g: context(A, B) () -> Unit, value: Any): context(A, B) () -> Unit { - return value as (context(A, B) () -> Unit) -} - -fun test() { - val lf: context(A, B) () -> Unit = { } -} diff --git a/compiler/testData/diagnostics/tests/extensions/contextReceivers/subtypingBetweenContextReceivers.kt b/compiler/testData/diagnostics/tests/extensions/contextReceivers/subtypingBetweenContextReceivers.kt index 05908907248..cfa156ee7ac 100644 --- a/compiler/testData/diagnostics/tests/extensions/contextReceivers/subtypingBetweenContextReceivers.kt +++ b/compiler/testData/diagnostics/tests/extensions/contextReceivers/subtypingBetweenContextReceivers.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNCHECKED_CAST // !LANGUAGE: +ContextReceivers diff --git a/compiler/testData/diagnostics/tests/extensions/contextReceivers/unsupported.fir.kt b/compiler/testData/diagnostics/tests/extensions/contextReceivers/unsupported.fir.kt index 9348aaf6f85..1ca66c727aa 100644 --- a/compiler/testData/diagnostics/tests/extensions/contextReceivers/unsupported.fir.kt +++ b/compiler/testData/diagnostics/tests/extensions/contextReceivers/unsupported.fir.kt @@ -1,8 +1,8 @@ // !DIAGNOSTICS: -UNCHECKED_CAST context(Any) -fun f(g: context(Any) () -> Unit, value: Any): context(A) () -> Unit { - return value as (context(A) () -> Unit) +fun f(g: context(Any) () -> Unit, value: Any): context(A) () -> Unit { + return value as (context(A) () -> Unit) } fun f(g: () -> Unit, value: Any) : () -> Unit {