Allow actuals with more permissive visibility
Allow non-virtual expects to have actuals with more permissive visibility. ^KT-19664 Fixed
This commit is contained in:
+15
-1
@@ -262,7 +262,7 @@ object ExpectedActualResolver {
|
||||
if (!equalsBy(aTypeParams, bTypeParams, TypeParameterDescriptor::getName)) return Incompatible.TypeParameterNames
|
||||
|
||||
if (!areCompatibleModalities(a.modality, b.modality)) return Incompatible.Modality
|
||||
if (a.visibility != b.visibility) return Incompatible.Visibility
|
||||
if (!areDeclarationsWithCompatibleVisibilities(a, b)) return Incompatible.Visibility
|
||||
|
||||
areCompatibleTypeParameters(aTypeParams, bTypeParams, platformModule, substitutor).let { if (it != Compatible) return it }
|
||||
|
||||
@@ -427,6 +427,20 @@ object ExpectedActualResolver {
|
||||
a == b
|
||||
}
|
||||
|
||||
private fun areDeclarationsWithCompatibleVisibilities(
|
||||
a: CallableMemberDescriptor,
|
||||
b: CallableMemberDescriptor
|
||||
): Boolean {
|
||||
val compare = Visibilities.compare(a.visibility, b.visibility)
|
||||
return if (a.isOverridable) {
|
||||
// For overridable declarations visibility should match precisely, see KT-19664
|
||||
compare == 0
|
||||
} else {
|
||||
// For non-overridable declarations actuals are allowed to have more permissive visibility
|
||||
compare != null && compare <= 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun areCompatibleClassScopes(
|
||||
a: ClassDescriptor,
|
||||
|
||||
Vendored
+4
-2
@@ -15,6 +15,7 @@ expect open class Container {
|
||||
protected fun protectedFun3()
|
||||
|
||||
open internal fun openInternalFun()
|
||||
open fun openPublicFun()
|
||||
}
|
||||
|
||||
// MODULE: m2-jvm(m1-common)
|
||||
@@ -24,14 +25,15 @@ expect open class Container {
|
||||
actual open class Container {
|
||||
actual fun publicFun() {} // OK: public -> public
|
||||
|
||||
actual fun <!ACTUAL_WITHOUT_EXPECT!>internalFun1<!>() {} // OK: internal -> public
|
||||
actual fun internalFun1() {} // OK: internal -> public
|
||||
actual internal fun internalFun2() {} // OK: internal -> internal
|
||||
|
||||
actual fun <!ACTUAL_WITHOUT_EXPECT!>protectedFun1<!>() {} // OK: protected -> public
|
||||
actual fun protectedFun1() {} // OK: protected -> public
|
||||
actual protected fun protectedFun2() {} // OK: protected -> protected
|
||||
|
||||
actual <!ACTUAL_WITHOUT_EXPECT!>internal<!> fun protectedFun3() {} // BAD: protected -> internal
|
||||
actual <!ACTUAL_WITHOUT_EXPECT!>protected<!> fun internalFun3() {} // BAD: internal -> protected
|
||||
|
||||
actual open fun <!ACTUAL_WITHOUT_EXPECT!>openInternalFun<!>() {} // BAD: internal+open -> public
|
||||
actual internal fun <!ACTUAL_WITHOUT_EXPECT!>openPublicFun<!>() {} // BAD: open+public -> internal
|
||||
}
|
||||
Vendored
+2
@@ -8,6 +8,7 @@ public open expect class Container {
|
||||
internal final expect fun internalFun2(): kotlin.Unit
|
||||
internal final expect fun internalFun3(): kotlin.Unit
|
||||
internal open expect fun openInternalFun(): kotlin.Unit
|
||||
public open expect fun openPublicFun(): kotlin.Unit
|
||||
protected final expect fun protectedFun1(): kotlin.Unit
|
||||
protected final expect fun protectedFun2(): kotlin.Unit
|
||||
protected final expect fun protectedFun3(): kotlin.Unit
|
||||
@@ -27,6 +28,7 @@ public open actual class Container {
|
||||
internal final actual fun internalFun2(): kotlin.Unit
|
||||
protected final actual fun internalFun3(): kotlin.Unit
|
||||
public open actual fun openInternalFun(): kotlin.Unit
|
||||
internal final actual fun openPublicFun(): kotlin.Unit
|
||||
public final actual fun protectedFun1(): kotlin.Unit
|
||||
protected final actual fun protectedFun2(): kotlin.Unit
|
||||
internal final actual fun protectedFun3(): kotlin.Unit
|
||||
|
||||
+1
-1
@@ -19,4 +19,4 @@ public class Foo {
|
||||
|
||||
// FILE: jvm.kt
|
||||
|
||||
actual typealias <!NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS!>Container<!> = foo.Foo
|
||||
actual typealias Container = foo.Foo
|
||||
@@ -125,12 +125,6 @@ The following declaration is incompatible because number of type parameters is d
|
||||
|
||||
actual fun <K, V> f7() {}
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/jvm.kt:16:1: error: actual function 'f8' has no corresponding expected declaration
|
||||
The following declaration is incompatible because visibility is different:
|
||||
internal expect fun f8(): Unit
|
||||
|
||||
public actual fun f8() {}
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/jvm.kt:17:1: error: actual function 'f10' has no corresponding expected declaration
|
||||
The following declaration is incompatible because visibility is different:
|
||||
public expect fun f10(): Unit
|
||||
|
||||
Reference in New Issue
Block a user