diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ResultClassInReturnTypeChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ResultClassInReturnTypeChecker.kt index aea3d6beb05..3b8be7b2a7c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ResultClassInReturnTypeChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ResultClassInReturnTypeChecker.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce import org.jetbrains.kotlin.psi.KtCallableDeclaration import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.types.KotlinType @@ -22,25 +23,24 @@ class ResultClassInReturnTypeChecker : DeclarationChecker { if (declaration !is KtCallableDeclaration || descriptor !is CallableMemberDescriptor) return val returnType = descriptor.returnType ?: return - if (isForbiddenReturnType(returnType, descriptor)) { + if (isForbiddenReturnType(returnType, declaration, descriptor)) { val typeReferenceOrDeclarationName = declaration.typeReference ?: declaration.nameIdentifier ?: return context.trace.reportDiagnosticOnce(Errors.RESULT_CLASS_IN_RETURN_TYPE.on(typeReferenceOrDeclarationName)) } } - private fun isForbiddenReturnType(returnType: KotlinType, declarationDescriptor: DeclarationDescriptor): Boolean { + private fun isForbiddenReturnType( + returnType: KotlinType, declaration: KtDeclaration, declarationDescriptor: DeclarationDescriptor + ): Boolean { if (!returnType.isResultType()) return false if (declarationDescriptor is PropertyDescriptor || declarationDescriptor is PropertyGetterDescriptor) { - val visibility = (declarationDescriptor as DeclarationDescriptorWithVisibility).effectiveVisibility() - return when (visibility) { - is EffectiveVisibility.Private, is EffectiveVisibility.Local, - is EffectiveVisibility.InternalOrPackage, is EffectiveVisibility.InternalProtected, - is EffectiveVisibility.InternalProtectedBound -> false - - is EffectiveVisibility.Public, is EffectiveVisibility.Protected, - is EffectiveVisibility.ProtectedBound -> true + if (declaration is KtProperty && declaration.getter?.hasBody() == true) { + return true } + + val visibility = (declarationDescriptor as DeclarationDescriptorWithVisibility).visibility + return !Visibilities.isPrivate(visibility) && visibility != Visibilities.LOCAL } return true diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt index c97c4a894e9..cbea3f5e0ab 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt @@ -138,6 +138,6 @@ object IObject { @JvmField val u = 42u - @JvmField - internal val r: Result = TODO() + @JvmField + private val r: Result = TODO() } diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.txt index 313a001f8b7..95857d5cd44 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.txt @@ -76,7 +76,7 @@ public interface I { public object IObject { private constructor IObject() @field:kotlin.jvm.JvmField public final val c: Foo - @field:kotlin.jvm.JvmField internal final val r: kotlin.Result + @field:kotlin.jvm.JvmField private final val r: kotlin.Result @field:kotlin.jvm.JvmField public final val u: kotlin.UInt = 42.toUInt() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/usageOfResultTypeInReturnType.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/usageOfResultTypeInReturnType.kt index ef657379712..367072f7075 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/usageOfResultTypeInReturnType.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/usageOfResultTypeInReturnType.kt @@ -28,10 +28,14 @@ fun returnContainer(): List> = TODO() val topLevelP: Result = TODO() val topLevelPInferred = topLevelP -internal val topLevelPInternal: Result = TODO() +internal val topLevelPInternal: Result = TODO() + private val topLevelPPrivate: Result = TODO() private val topLevelPPrivateInferred = topLevelP +private val topLevelPPrivateCustomGetter: Result + get() = TODO() + val asFunctional: () -> Result = TODO() open class PublicCls( @@ -41,7 +45,9 @@ open class PublicCls( val r4: ResultAlias?, val r5: InlineResult, - internal val r6: Result, + + internal val r6: Result, + private val r7: Result, val r8: List> ) { @@ -51,11 +57,11 @@ open class PublicCls( val p4 = p1 - internal val p5: Result = TODO() + internal val p5: Result = TODO() + private var p6: Result = TODO() - internal val p7 = p1 - + internal val p7 = p1 protected val p8 = p1 fun returnInCls(): Result = TODO() @@ -64,36 +70,38 @@ open class PublicCls( } internal open class InternalCls( - val r1: Result, - val r2: ResultAlias?, + val r1: Result, + val r2: ResultAlias?, + val r3: List> ) { companion object { - val cr1: Result = TODO() + val cr1: Result = TODO() + private val cr2: Result = TODO() } - val p1 = r1 - val p2: Result = TODO() + val p1 = r1 + val p2: Result = TODO() - protected val p3 = p1 + protected val p3 = p1 fun returnInInternal(): Result = TODO() protected fun returnInClsProtected(): Result = TODO() } private class PrivateCls( - val r1: Result, - val r2: ResultAlias?, + val r1: Result, + val r2: ResultAlias?, val r3: List> ) { companion object { - val cr1: Result = TODO() + val cr1: Result = TODO() private val cr2: Result = TODO() } - val p1 = r1 - val p2: Result = TODO() + val p1 = r1 + val p2: Result = TODO() fun returnInPrivate(): Result = TODO() } @@ -105,8 +113,8 @@ fun local(r: Result) { fun localFun(): Result = TODO() class F { - val p1: Result = r - val p2 = r + val p1: Result = r + val p2 = r } } diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/usageOfResultTypeInReturnType.txt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/usageOfResultTypeInReturnType.txt index 2f64b4383af..9f5253f8fbc 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/usageOfResultTypeInReturnType.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/usageOfResultTypeInReturnType.txt @@ -7,6 +7,7 @@ public val topLevelP: kotlin.Result public val topLevelPInferred: kotlin.Result internal val topLevelPInternal: kotlin.Result private val topLevelPPrivate: kotlin.Result +private val topLevelPPrivateCustomGetter: kotlin.Result private val topLevelPPrivateInferred: kotlin.Result public fun local(/*0*/ r: kotlin.Result): kotlin.Unit public fun params(/*0*/ r1: kotlin.Result, /*1*/ r2: kotlin.Result?, /*2*/ r3: ResultAlias /* = kotlin.Result */, /*3*/ r4: kotlin.collections.List>, /*4*/ r5: InlineResult, /*5*/ vararg r6: kotlin.Result /*kotlin.Array>*/): kotlin.Unit diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/usageOfResultTypeWithNullableOperators.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/usageOfResultTypeWithNullableOperators.kt index 703385d091b..bbd5a0b0639 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/usageOfResultTypeWithNullableOperators.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/usageOfResultTypeWithNullableOperators.kt @@ -3,7 +3,7 @@ fun id(x: T): T = x private val asFun: () -> Result? = TODO() -private val Int.intResult: Result? +private val Int.intResult: Result? get() = null fun returnInt(): Int? = 0