diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index 76273912f07..cf03a173479 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -34309,6 +34309,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/fullFqNameUsage.kt"); } + @Test + @TestMetadata("implicitUsages.kt") + public void testImplicitUsages() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.kt"); + } + @Test @TestMetadata("importStatement.kt") public void testImportStatement() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 8f6b68ddf7f..618492140c1 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -34309,6 +34309,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/fullFqNameUsage.kt"); } + @Test + @TestMetadata("implicitUsages.kt") + public void testImplicitUsages() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.kt"); + } + @Test @TestMetadata("importStatement.kt") public void testImportStatement() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt index 5b8aab4b64c..3d60f904c96 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt @@ -46,6 +46,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.storage.LockBasedStorageManager +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.isError import org.jetbrains.kotlin.utils.SmartSet import org.jetbrains.kotlin.utils.addIfNotNull @@ -79,11 +81,36 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { ) override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) { - val experimentalities = - resolvedCall.resultingDescriptor.loadExperimentalities(moduleAnnotationsResolver, context.languageVersionSettings) + val resultingDescriptor = resolvedCall.resultingDescriptor + val experimentalities = resultingDescriptor.loadExperimentalities(moduleAnnotationsResolver, context.languageVersionSettings) + if (resultingDescriptor is FunctionDescriptor && + resultingDescriptor.kind == CallableMemberDescriptor.Kind.SYNTHESIZED + ) { + val propertyDescriptor = resultingDescriptor.findRelevantDataClassPropertyIfAny(context) + if (propertyDescriptor != null) { + reportNotAcceptedExperimentalities( + experimentalities + propertyDescriptor.loadExperimentalities( + moduleAnnotationsResolver, context.languageVersionSettings + ), reportOn, context + ) + return + } + } reportNotAcceptedExperimentalities(experimentalities, reportOn, context) } + private fun FunctionDescriptor.findRelevantDataClassPropertyIfAny(context: CallCheckerContext): PropertyDescriptor? { + val index = name.asString().removePrefix("component").toIntOrNull() + val container = containingDeclaration + if (container is ClassDescriptor && container.isData && index != null) { + val dataClassParameterDescriptor = container.unsubstitutedPrimaryConstructor?.valueParameters?.getOrNull(index - 1) + if (dataClassParameterDescriptor != null) { + return context.trace.bindingContext[BindingContext.VALUE_PARAMETER_AS_PROPERTY, dataClassParameterDescriptor] + } + } + return null + } + companion object { val OLD_EXPERIMENTAL_FQ_NAME = FqName("kotlin.Experimental") val OLD_USE_EXPERIMENTAL_FQ_NAME = FqName("kotlin.UseExperimental") @@ -145,14 +172,47 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { fun DeclarationDescriptor.loadExperimentalities( moduleAnnotationsResolver: ModuleAnnotationsResolver, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + visited: MutableSet = mutableSetOf() ): Set { + if (this in visited) return emptySet() + visited += this val result = SmartSet.create() + if (this is CallableMemberDescriptor && kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + for (overridden in overriddenDescriptors) { + result.addAll(overridden.loadExperimentalities(moduleAnnotationsResolver, languageVersionSettings, visited)) + } + return result + } for (annotation in annotations) { result.addIfNotNull(annotation.annotationClass?.loadExperimentalityForMarkerAnnotation()) } + if (this is CallableDescriptor && this !is ClassConstructorDescriptor) { + result.addAll( + returnType.loadExperimentalities(moduleAnnotationsResolver, languageVersionSettings, visited) + ) + result.addAll( + extensionReceiverParameter?.type.loadExperimentalities( + moduleAnnotationsResolver, languageVersionSettings, visited + ) + ) + if (this is FunctionDescriptor) { + valueParameters.forEach { + result.addAll( + it.type.loadExperimentalities( + moduleAnnotationsResolver, languageVersionSettings, visited + ) + ) + } + } + } + + if (this is TypeAliasDescriptor) { + result.addAll(expandedType.loadExperimentalities(moduleAnnotationsResolver, languageVersionSettings, visited)) + } + if (annotations.any { it.fqName == WAS_EXPERIMENTAL_FQ_NAME }) { val accessibility = checkSinceKotlinVersionAccessibility(languageVersionSettings) if (accessibility is SinceKotlinAccessibility.NotAccessibleButWasExperimental) { @@ -162,7 +222,7 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { val container = containingDeclaration if (container is ClassDescriptor && this !is ConstructorDescriptor) { - result.addAll(container.loadExperimentalities(moduleAnnotationsResolver, languageVersionSettings)) + result.addAll(container.loadExperimentalities(moduleAnnotationsResolver, languageVersionSettings, visited)) } for (moduleAnnotationClassId in moduleAnnotationsResolver.getAnnotationsOnContainingModule(this)) { @@ -173,6 +233,19 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { return result } + private fun KotlinType?.loadExperimentalities( + moduleAnnotationsResolver: ModuleAnnotationsResolver, + languageVersionSettings: LanguageVersionSettings, + visitedClassifiers: MutableSet + ): Set = + if (this?.isError != false) emptySet() + else constructor.declarationDescriptor?.loadExperimentalities( + moduleAnnotationsResolver, languageVersionSettings, visitedClassifiers + ).orEmpty() + arguments.flatMap { + if (it.isStarProjection) emptySet() + else it.type.loadExperimentalities(moduleAnnotationsResolver, languageVersionSettings, visitedClassifiers) + } + internal fun ClassDescriptor.loadExperimentalityForMarkerAnnotation(): Experimentality? { val experimental = annotations.findAnnotation(REQUIRES_OPT_IN_FQ_NAME) @@ -316,7 +389,15 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { } if (element.getParentOfType(false) == null) { - val experimentalities = targetDescriptor.loadExperimentalities(moduleAnnotationsResolver, context.languageVersionSettings) + val experimentalities = mutableSetOf() + experimentalities += targetDescriptor.loadExperimentalities(moduleAnnotationsResolver, context.languageVersionSettings) + if (targetDescriptor is TypeAliasDescriptor) { + experimentalities.addAll( + targetDescriptor.expandedType.loadExperimentalities( + moduleAnnotationsResolver, context.languageVersionSettings, mutableSetOf(targetDescriptor) + ) + ) + } reportNotAcceptedExperimentalities(experimentalities, element, context) } } diff --git a/compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.out b/compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.out index a239b5a8eb5..d649a1aa0ef 100644 --- a/compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.out +++ b/compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.out @@ -11,4 +11,13 @@ compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.kt:2:5: compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.kt:4:12: error: this declaration is experimental and its usage must be marked with '@kotlin.ExperimentalStdlibApi' or '@OptIn(kotlin.ExperimentalStdlibApi::class)' val x: ArrayDeque? = null ^ +compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.kt:5:12: error: this declaration is experimental and its usage must be marked with '@kotlin.ExperimentalStdlibApi' or '@OptIn(kotlin.ExperimentalStdlibApi::class)' + return x ?: s + ^ +compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.kt:5:14: error: this declaration is experimental and its usage must be marked with '@kotlin.ExperimentalStdlibApi' or '@OptIn(kotlin.ExperimentalStdlibApi::class)' + return x ?: s + ^ +compiler/testData/cli/jvm/useDeclarationThatWasExperimentalWithoutMarker.kt:5:17: error: this declaration is experimental and its usage must be marked with '@kotlin.ExperimentalStdlibApi' or '@OptIn(kotlin.ExperimentalStdlibApi::class)' + return x ?: s + ^ COMPILATION_ERROR diff --git a/compiler/testData/diagnostics/tests/regressions/ea76264.kt b/compiler/testData/diagnostics/tests/regressions/ea76264.kt index 941e1fac55e..b33f1c33d2b 100644 --- a/compiler/testData/diagnostics/tests/regressions/ea76264.kt +++ b/compiler/testData/diagnostics/tests/regressions/ea76264.kt @@ -1,4 +1,4 @@ // StackOverflow -val p = ::p +val p = ::p -fun foo() = ::foo \ No newline at end of file +fun foo() = ::foo diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembers.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembers.kt index 8e416c446d8..b0b6b1e44d8 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembers.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembers.kt @@ -81,9 +81,9 @@ import api.* fun use() { val c: C = C() - c.function() - c.property + c.function() + c.property C.Nested() - c.Inner() - c.extension() + c.Inner() + c.extension() } diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembersOverlyExperimental.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembersOverlyExperimental.kt index 9a740c921be..91c7e04a3d9 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembersOverlyExperimental.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembersOverlyExperimental.kt @@ -31,7 +31,7 @@ import api.* fun use() { val c: C = C() - c.function() - c.property + c.function() + c.property C.Nested().nestedFunction() } diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/deeplyNestedClass.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/deeplyNestedClass.kt index 3a32420b1eb..32e03d8a48d 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/deeplyNestedClass.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/deeplyNestedClass.kt @@ -55,4 +55,4 @@ fun use1() { C.D.E.F() } -fun use2(f: C.D.E.F) = f.hashCode() +fun use2(f: C.D.E.F) = f.hashCode() diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.fir.kt new file mode 100644 index 00000000000..94442c9201f --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.fir.kt @@ -0,0 +1,113 @@ +// !USE_EXPERIMENTAL: kotlin.RequiresOptIn + +@RequiresOptIn +@Retention(AnnotationRetention.BINARY) +annotation class Marker + +@Marker +interface Some + +abstract class User { + abstract fun createSome(): Some + fun Some?.onSome() {} + fun withSome(some: Some? = null) {} + + fun use() { + val something = createSome() + val somethingOther: Some = createSome() + null.onSome() + withSome() + } +} + +data class DataClass(@property:Marker val x: Int) + +fun useDataClass(d: DataClass) { + // Should have error in both + d.x + val (x) = d +} + +typealias My = Some + +fun my(my: My) {} + +fun your(my: Some) {} + +@Marker +interface ExperimentalType { + fun foo() {} + fun bar() {} +} + +@OptIn(Marker::class) +interface NotExperimentalExtension : ExperimentalType { + override fun foo() {} +} + +fun use(arg: NotExperimentalExtension) { + arg.foo() + arg.bar() +} + +@Marker +interface I + +@OptIn(Marker::class) +class A : I + +@OptIn(Marker::class) +class B : I + +fun main() { + val x = listOf(A(), B()) +} + +@Marker +class C { + operator fun getValue(x: Any?, y: Any?): String = "" +} + +object O { + @OptIn(Marker::class) + operator fun provideDelegate(x: Any?, y: Any?): C = C() +} + +val x: String by O + +@Marker +class OperatorContainer : Comparable { + @OptIn(Marker::class) + override fun compareTo(other: OperatorContainer): Int { + return 0 + } +} + +@OptIn(Marker::class) +class AnotherContainer : Iterable { + @OptIn(Marker::class) + override fun iterator(): Iterator { + return object : Iterator { + override fun hasNext(): Boolean { + return false + } + + override fun next(): C { + throw java.util.NoSuchElementException() + } + } + } +} + +@OptIn(Marker::class) +operator fun String.minus(s: String) = OperatorContainer() + +@OptIn(Marker::class) +operator fun String.invoke() = OperatorContainer() + +fun operatorContainerUsage(s: String, a: AnotherContainer) { + val res1 = s - s + val res2 = s() + val res3 = res1 > res2 + for (c in a) {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.kt new file mode 100644 index 00000000000..27bc48e8bbd --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.kt @@ -0,0 +1,113 @@ +// !USE_EXPERIMENTAL: kotlin.RequiresOptIn + +@RequiresOptIn +@Retention(AnnotationRetention.BINARY) +annotation class Marker + +@Marker +interface Some + +abstract class User { + abstract fun createSome(): Some + fun Some?.onSome() {} + fun withSome(some: Some? = null) {} + + fun use() { + val something = createSome() + val somethingOther: Some = createSome() + null.onSome() + withSome() + } +} + +data class DataClass(@property:Marker val x: Int) + +fun useDataClass(d: DataClass) { + // Should have error in both + d.x + val (x) = d +} + +typealias My = Some + +fun my(my: My) {} + +fun your(my: Some) {} + +@Marker +interface ExperimentalType { + fun foo() {} + fun bar() {} +} + +@OptIn(Marker::class) +interface NotExperimentalExtension : ExperimentalType { + override fun foo() {} +} + +fun use(arg: NotExperimentalExtension) { + arg.foo() + arg.bar() +} + +@Marker +interface I + +@OptIn(Marker::class) +class A : I + +@OptIn(Marker::class) +class B : I + +fun main() { + val x = listOf(A(), B()) +} + +@Marker +class C { + operator fun getValue(x: Any?, y: Any?): String = "" +} + +object O { + @OptIn(Marker::class) + operator fun provideDelegate(x: Any?, y: Any?): C = C() +} + +val x: String by O + +@Marker +class OperatorContainer : Comparable { + @OptIn(Marker::class) + override fun compareTo(other: OperatorContainer): Int { + return 0 + } +} + +@OptIn(Marker::class) +class AnotherContainer : Iterable { + @OptIn(Marker::class) + override fun iterator(): Iterator { + return object : Iterator { + override fun hasNext(): Boolean { + return false + } + + override fun next(): C { + throw java.util.NoSuchElementException() + } + } + } +} + +@OptIn(Marker::class) +operator fun String.minus(s: String) = OperatorContainer() + +@OptIn(Marker::class) +operator fun String.invoke() = OperatorContainer() + +fun operatorContainerUsage(s: String, a: AnotherContainer) { + val res1 = s - s + val res2 = s() + val res3 = res1 > res2 + for (c in a) {} +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.txt b/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.txt new file mode 100644 index 00000000000..3fb030697dd --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.txt @@ -0,0 +1,115 @@ +package + +public val x: kotlin.String +public fun main(): kotlin.Unit +public fun my(/*0*/ my: My /* = Some */): kotlin.Unit +public fun operatorContainerUsage(/*0*/ s: kotlin.String, /*1*/ a: AnotherContainer): kotlin.Unit +public fun use(/*0*/ arg: NotExperimentalExtension): kotlin.Unit +public fun useDataClass(/*0*/ d: DataClass): kotlin.Unit +public fun your(/*0*/ my: Some): kotlin.Unit +@kotlin.OptIn(markerClass = {Marker::class}) public operator fun kotlin.String.invoke(): OperatorContainer +@kotlin.OptIn(markerClass = {Marker::class}) public operator fun kotlin.String.minus(/*0*/ s: kotlin.String): OperatorContainer + +@kotlin.OptIn(markerClass = {Marker::class}) public final class A : I { + public constructor A() + 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 +} + +@kotlin.OptIn(markerClass = {Marker::class}) public final class AnotherContainer : kotlin.collections.Iterable { + public constructor AnotherContainer() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + @kotlin.OptIn(markerClass = {Marker::class}) public open override /*1*/ fun iterator(): kotlin.collections.Iterator + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.OptIn(markerClass = {Marker::class}) public final class B : I { + public constructor B() + 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 +} + +@Marker public final class C { + public constructor C() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final operator fun getValue(/*0*/ x: kotlin.Any?, /*1*/ y: kotlin.Any?): kotlin.String + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final data class DataClass { + public constructor DataClass(/*0*/ x: kotlin.Int) + @Marker public final val x: kotlin.Int + public final operator /*synthesized*/ fun component1(): kotlin.Int + public final /*synthesized*/ fun copy(/*0*/ x: kotlin.Int = ...): DataClass + public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String +} + +@Marker public interface ExperimentalType { + public open fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@Marker public interface I { + 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 +} + +@kotlin.RequiresOptIn @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) public final annotation class Marker : kotlin.Annotation { + public constructor Marker() + 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 +} + +@kotlin.OptIn(markerClass = {Marker::class}) public interface NotExperimentalExtension : ExperimentalType { + public open override /*1*/ /*fake_override*/ fun bar(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ fun foo(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public object O { + private constructor O() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + @kotlin.OptIn(markerClass = {Marker::class}) public final operator fun provideDelegate(/*0*/ x: kotlin.Any?, /*1*/ y: kotlin.Any?): C + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@Marker public final class OperatorContainer : kotlin.Comparable { + public constructor OperatorContainer() + @kotlin.OptIn(markerClass = {Marker::class}) public open override /*1*/ fun compareTo(/*0*/ other: OperatorContainer): 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 +} + +@Marker public interface Some { + 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 User { + public constructor User() + public abstract fun createSome(): Some + 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 fun use(): kotlin.Unit + public final fun withSome(/*0*/ some: Some? = ...): kotlin.Unit + public final fun Some?.onSome(): kotlin.Unit +} +public typealias My = Some + diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 58f8724969e..62a23711352 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -34405,6 +34405,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/fullFqNameUsage.kt"); } + @Test + @TestMetadata("implicitUsages.kt") + public void testImplicitUsages() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.kt"); + } + @Test @TestMetadata("importStatement.kt") public void testImportStatement() throws Exception { diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/api/fixes/KtQuickFixesList.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/api/fixes/KtQuickFixesList.kt index 315513438e1..a3a3edfb3f3 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/api/fixes/KtQuickFixesList.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/api/fixes/KtQuickFixesList.kt @@ -16,6 +16,7 @@ import kotlin.reflect.KClass class KtQuickFixesList @ForKtQuickFixesListBuilder @OptIn(PrivateForInline::class) constructor( private val quickFixes: Map>, List> ) { + @OptIn(PrivateForInline::class) fun KtAnalysisSession.getQuickFixesFor(diagnostic: KtDiagnosticWithPsi<*>): List { val factories = quickFixes[diagnostic.diagnosticClass] ?: return emptyList() return factories.flatMap { createQuickFixes(it, diagnostic) } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 1889e7e197c..6375a14a57c 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/tests/org/jetbrains/kotlin/idea/fir/low/level/api/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -30126,6 +30126,11 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/fullFqNameUsage.kt"); } + @TestMetadata("implicitUsages.kt") + public void testImplicitUsages() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsages.kt"); + } + @TestMetadata("importStatement.kt") public void testImportStatement() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/importStatement.kt"); diff --git a/idea/testData/multiModuleHighlighting/jsExperimentalLibrary/usage/usage.kt b/idea/testData/multiModuleHighlighting/jsExperimentalLibrary/usage/usage.kt index 49c4e43e1a5..968097b7965 100644 --- a/idea/testData/multiModuleHighlighting/jsExperimentalLibrary/usage/usage.kt +++ b/idea/testData/multiModuleHighlighting/jsExperimentalLibrary/usage/usage.kt @@ -4,7 +4,7 @@ import lib.* fun fail(foo: Foo): Foo { bar() - return foo + return foo } @ExperimentalAPI diff --git a/idea/testData/multiModuleHighlighting/jvmExperimentalLibrary/usage/usage.kt b/idea/testData/multiModuleHighlighting/jvmExperimentalLibrary/usage/usage.kt index 49c4e43e1a5..968097b7965 100644 --- a/idea/testData/multiModuleHighlighting/jvmExperimentalLibrary/usage/usage.kt +++ b/idea/testData/multiModuleHighlighting/jvmExperimentalLibrary/usage/usage.kt @@ -4,7 +4,7 @@ import lib.* fun fail(foo: Foo): Foo { bar() - return foo + return foo } @ExperimentalAPI diff --git a/plugins/kotlin-serialization/kotlin-serialization-ide/testData/diagnostics/JsonRedundantFormat.kt b/plugins/kotlin-serialization/kotlin-serialization-ide/testData/diagnostics/JsonRedundantFormat.kt index 10bb0fe3f6a..55d8ce46e57 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-ide/testData/diagnostics/JsonRedundantFormat.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-ide/testData/diagnostics/JsonRedundantFormat.kt @@ -1,4 +1,4 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE +// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE,-EXPERIMENTAL_API_USAGE // SKIP_TXT // FILE: test.kt