[FIR] Move check for _private-to-this_ visibility into checker
^KT-55446 ^KT-65790 Fixed
This commit is contained in:
committed by
Space Team
parent
5fe1e0c1a5
commit
c64575f4a2
+1
@@ -54,6 +54,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
||||
FirMissingDependencyClassChecker,
|
||||
FirMissingDependencySupertypeInQualifiedAccessExpressionsChecker,
|
||||
FirArrayOfNothingQualifierChecker,
|
||||
FirPrivateToThisAccessChecker,
|
||||
)
|
||||
|
||||
override val callCheckers: Set<FirCallChecker>
|
||||
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.containingClassLookupTag
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.visibility
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.toReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedErrorReference
|
||||
import org.jetbrains.kotlin.fir.references.FirThisReference
|
||||
import org.jetbrains.kotlin.fir.references.resolved
|
||||
import org.jetbrains.kotlin.fir.references.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeSetterVisibilityError
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeVisibilityError
|
||||
import org.jetbrains.kotlin.fir.resolve.toClassSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.unwrapFakeOverrides
|
||||
import org.jetbrains.kotlin.types.EnrichedProjectionKind
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
object FirPrivateToThisAccessChecker : FirQualifiedAccessExpressionChecker(MppCheckerKind.Common) {
|
||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val reference = expression.calleeReference.resolved ?: return
|
||||
if (reference is FirResolvedErrorReference) {
|
||||
// If there was a visibility diagnostic, no need to report another one about visibility
|
||||
when (reference.diagnostic) {
|
||||
is ConeVisibilityError,
|
||||
is ConeSetterVisibilityError -> return
|
||||
}
|
||||
}
|
||||
val dispatchReceiver = expression.dispatchReceiver ?: return
|
||||
val symbol = reference.toResolvedCallableSymbol(discardErrorReference = true) ?: return
|
||||
if (symbol.visibility != Visibilities.Private) return
|
||||
val session = context.session
|
||||
val containingClassSymbol = symbol.containingClassLookupTag()?.toClassSymbol(session)
|
||||
|
||||
if (!isPrivateToThis(symbol.unwrapFakeOverrides(), containingClassSymbol, session)) return
|
||||
|
||||
val invisible = when (val receiverReference = dispatchReceiver.toReference(session)) {
|
||||
is FirThisReference -> receiverReference.boundSymbol != containingClassSymbol
|
||||
else -> true
|
||||
}
|
||||
|
||||
if (invisible) {
|
||||
reporter.reportOn(
|
||||
source = expression.source,
|
||||
factory = FirErrors.INVISIBLE_REFERENCE,
|
||||
symbol,
|
||||
Visibilities.PrivateToThis,
|
||||
symbol.callableId.classId,
|
||||
context,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isPrivateToThis(
|
||||
symbol: FirCallableSymbol<*>,
|
||||
containingClassSymbol: FirClassSymbol<*>?,
|
||||
session: FirSession
|
||||
): Boolean {
|
||||
if (containingClassSymbol == null) return false
|
||||
if (symbol is FirConstructorSymbol) return false
|
||||
if (containingClassSymbol.typeParameterSymbols.all { it.variance == Variance.INVARIANT }) return false
|
||||
|
||||
if (symbol.receiverParameter?.typeRef?.coneType?.contradictsWith(Variance.IN_VARIANCE, session) == true) {
|
||||
return true
|
||||
}
|
||||
if (symbol.resolvedReturnType.contradictsWith(
|
||||
if (symbol is FirPropertySymbol && symbol.isVar) Variance.INVARIANT
|
||||
else Variance.OUT_VARIANCE,
|
||||
session
|
||||
)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
if (symbol is FirFunctionSymbol<*>) {
|
||||
for (parameter in symbol.valueParameterSymbols) {
|
||||
if (parameter.resolvedReturnType.contradictsWith(Variance.IN_VARIANCE, session)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.contradictsWith(requiredVariance: Variance, session: FirSession): Boolean {
|
||||
when (this) {
|
||||
is ConeLookupTagBasedType -> {
|
||||
if (this is ConeTypeParameterType) {
|
||||
return !this.lookupTag.typeParameterSymbol.variance.allowsPosition(requiredVariance)
|
||||
}
|
||||
if (this is ConeClassLikeType) {
|
||||
// It's safe to access fir here, because later we access only variance of type parameters of the class
|
||||
// And variance can not be changed after raw fir stage
|
||||
@OptIn(SymbolInternals::class)
|
||||
val classLike = this.lookupTag.toSymbol(session)?.fir ?: return false
|
||||
for ((index, argument) in this.typeArguments.withIndex()) {
|
||||
val typeParameterRef = classLike.typeParameters.getOrNull(index)
|
||||
if (typeParameterRef !is FirTypeParameter) continue
|
||||
val requiredVarianceForArgument = when (
|
||||
EnrichedProjectionKind.getEffectiveProjectionKind(typeParameterRef.variance, argument.variance)
|
||||
) {
|
||||
EnrichedProjectionKind.OUT -> requiredVariance
|
||||
EnrichedProjectionKind.IN -> requiredVariance.opposite()
|
||||
EnrichedProjectionKind.INV -> Variance.INVARIANT
|
||||
EnrichedProjectionKind.STAR -> continue // CONFLICTING_PROJECTION error was reported
|
||||
}
|
||||
val argType = argument.type ?: continue
|
||||
if (argType.contradictsWith(requiredVarianceForArgument, session)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is ConeFlexibleType -> {
|
||||
return lowerBound.contradictsWith(requiredVariance, session)
|
||||
}
|
||||
is ConeDefinitelyNotNullType -> {
|
||||
return original.contradictsWith(requiredVariance, session)
|
||||
}
|
||||
is ConeIntersectionType -> {
|
||||
return this.intersectedTypes.any { it.contradictsWith(requiredVariance, session) }
|
||||
}
|
||||
is ConeCapturedType -> {
|
||||
// Looks like not possible here
|
||||
return false
|
||||
}
|
||||
is ConeIntegerConstantOperatorType,
|
||||
is ConeIntegerLiteralConstantType,
|
||||
is ConeStubTypeForChainInference,
|
||||
is ConeStubTypeForTypeVariableInSubtyping,
|
||||
is ConeTypeVariableType,
|
||||
-> return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private val ConeTypeProjection.variance: Variance
|
||||
get() = when (this.kind) {
|
||||
ProjectionKind.STAR -> Variance.OUT_VARIANCE
|
||||
ProjectionKind.IN -> Variance.IN_VARIANCE
|
||||
ProjectionKind.OUT -> Variance.OUT_VARIANCE
|
||||
ProjectionKind.INVARIANT -> Variance.INVARIANT
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,12 @@ fun ConeClassLikeLookupTag.toSymbol(useSiteSession: FirSession): FirClassLikeSym
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see toSymbol
|
||||
*/
|
||||
fun ConeClassLikeLookupTag.toClassSymbol(session: FirSession): FirClassSymbol<*>? =
|
||||
toSymbol(session) as? FirClassSymbol<*>
|
||||
|
||||
/**
|
||||
* @see toSymbol
|
||||
*/
|
||||
|
||||
+2
-107
@@ -15,15 +15,12 @@ import org.jetbrains.kotlin.fir.extensions.FirStatusTransformerExtension
|
||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||
import org.jetbrains.kotlin.fir.extensions.statusTransformerExtensions
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope
|
||||
import org.jetbrains.kotlin.fir.toEffectiveVisibility
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
|
||||
import org.jetbrains.kotlin.fir.visibilityChecker
|
||||
import org.jetbrains.kotlin.types.EnrichedProjectionKind
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
|
||||
|
||||
class FirStatusResolver(
|
||||
@@ -41,7 +38,7 @@ class FirStatusResolver(
|
||||
)
|
||||
|
||||
private val MODIFIERS_FROM_OVERRIDDEN: List<FirDeclarationStatusImpl.Modifier> =
|
||||
FirDeclarationStatusImpl.Modifier.values().toList() - NOT_INHERITED_MODIFIERS
|
||||
FirDeclarationStatusImpl.Modifier.entries - NOT_INHERITED_MODIFIERS
|
||||
}
|
||||
|
||||
private val extensionStatusTransformers = session.extensionService.statusTransformerExtensions
|
||||
@@ -247,18 +244,7 @@ class FirStatusResolver(
|
||||
isLocal -> Visibilities.Local
|
||||
else -> resolveVisibility(declaration, containingClass, containingProperty, overriddenStatuses)
|
||||
}
|
||||
|
||||
Visibilities.Private -> when {
|
||||
declaration is FirPropertyAccessor -> if (containingProperty?.visibility == Visibilities.PrivateToThis) {
|
||||
Visibilities.PrivateToThis
|
||||
} else {
|
||||
Visibilities.Private
|
||||
}
|
||||
|
||||
isPrivateToThis(declaration, containingClass) -> Visibilities.PrivateToThis
|
||||
else -> Visibilities.Private
|
||||
}
|
||||
|
||||
Visibilities.Private -> Visibilities.Private
|
||||
else -> status.visibility
|
||||
}
|
||||
|
||||
@@ -317,97 +303,6 @@ class FirStatusResolver(
|
||||
return status.resolved(visibility, modality, effectiveVisibility)
|
||||
}
|
||||
|
||||
private fun isPrivateToThis(
|
||||
declaration: FirDeclaration,
|
||||
containingClass: FirClass?,
|
||||
): Boolean {
|
||||
if (containingClass == null) return false
|
||||
if (declaration !is FirCallableDeclaration) return false
|
||||
if (declaration is FirConstructor) return false
|
||||
if (containingClass.typeParameters.all { it.symbol.variance == Variance.INVARIANT }) return false
|
||||
|
||||
if (declaration.receiverParameter?.typeRef?.contradictsWith(Variance.IN_VARIANCE) == true) {
|
||||
return true
|
||||
}
|
||||
if (declaration.returnTypeRef.contradictsWith(
|
||||
if (declaration is FirProperty && declaration.isVar) Variance.INVARIANT
|
||||
else Variance.OUT_VARIANCE
|
||||
)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
if (declaration is FirFunction) {
|
||||
for (parameter in declaration.valueParameters) {
|
||||
if (parameter.returnTypeRef.contradictsWith(Variance.IN_VARIANCE)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun FirTypeRef.contradictsWith(requiredVariance: Variance): Boolean {
|
||||
val type = coneTypeSafe<ConeKotlinType>() ?: return false
|
||||
return contradictsWith(type, requiredVariance)
|
||||
}
|
||||
|
||||
private fun contradictsWith(type: ConeKotlinType, requiredVariance: Variance): Boolean {
|
||||
when (type) {
|
||||
is ConeLookupTagBasedType -> {
|
||||
if (type is ConeTypeParameterType) {
|
||||
return !type.lookupTag.typeParameterSymbol.fir.variance.allowsPosition(requiredVariance)
|
||||
}
|
||||
if (type is ConeClassLikeType) {
|
||||
val classLike = type.lookupTag.toSymbol(session)?.fir
|
||||
for ((index, argument) in type.typeArguments.withIndex()) {
|
||||
val typeParameterRef = classLike?.typeParameters?.getOrNull(index)
|
||||
if (typeParameterRef !is FirTypeParameter) continue
|
||||
val requiredVarianceForArgument = when (
|
||||
EnrichedProjectionKind.getEffectiveProjectionKind(typeParameterRef.variance, argument.variance)
|
||||
) {
|
||||
EnrichedProjectionKind.OUT -> requiredVariance
|
||||
EnrichedProjectionKind.IN -> requiredVariance.opposite()
|
||||
EnrichedProjectionKind.INV -> Variance.INVARIANT
|
||||
EnrichedProjectionKind.STAR -> continue // CONFLICTING_PROJECTION error was reported
|
||||
}
|
||||
val argType = argument.type ?: continue
|
||||
if (contradictsWith(argType, requiredVarianceForArgument)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is ConeFlexibleType -> {
|
||||
return contradictsWith(type.lowerBound, requiredVariance)
|
||||
}
|
||||
is ConeDefinitelyNotNullType -> {
|
||||
return contradictsWith(type.original, requiredVariance)
|
||||
}
|
||||
is ConeIntersectionType -> {
|
||||
return type.intersectedTypes.any { contradictsWith(it, requiredVariance) }
|
||||
}
|
||||
is ConeCapturedType -> {
|
||||
// Looks like not possible here
|
||||
return false
|
||||
}
|
||||
is ConeIntegerConstantOperatorType,
|
||||
is ConeIntegerLiteralConstantType,
|
||||
is ConeStubTypeForChainInference,
|
||||
is ConeStubTypeForTypeVariableInSubtyping,
|
||||
is ConeTypeVariableType,
|
||||
-> return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private val ConeTypeProjection.variance: Variance
|
||||
get() = when (this.kind) {
|
||||
ProjectionKind.STAR -> Variance.OUT_VARIANCE
|
||||
ProjectionKind.IN -> Variance.IN_VARIANCE
|
||||
ProjectionKind.OUT -> Variance.OUT_VARIANCE
|
||||
ProjectionKind.INVARIANT -> Variance.INVARIANT
|
||||
}
|
||||
|
||||
private fun resolveVisibility(
|
||||
declaration: FirDeclaration,
|
||||
containingClass: FirClass?,
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ class Test<in I> {
|
||||
apply(foo())
|
||||
apply(this.foo())
|
||||
with(Test<I>()) {
|
||||
apply(foo()) // resolved to this@Test.foo
|
||||
apply(<!INVISIBLE_REFERENCE!>foo<!>()) // K1: this@Test.foo, K2: this@with.foo, see KT-55446
|
||||
apply(this.<!INVISIBLE_REFERENCE!>foo<!>())
|
||||
apply(this@with.<!INVISIBLE_REFERENCE!>foo<!>())
|
||||
apply(this@Test.foo())
|
||||
|
||||
@@ -14,7 +14,7 @@ class Test<in I> {
|
||||
apply(foo())
|
||||
apply(this.foo())
|
||||
with(Test<I>()) {
|
||||
apply(foo()) // resolved to this@Test.foo
|
||||
apply(foo()) // K1: this@Test.foo, K2: this@with.foo, see KT-55446
|
||||
apply(this.<!INVISIBLE_MEMBER("foo; private/*private to this*/; 'Test'")!>foo<!>())
|
||||
apply(this@with.<!INVISIBLE_MEMBER("foo; private/*private to this*/; 'Test'")!>foo<!>())
|
||||
apply(this@Test.foo())
|
||||
|
||||
@@ -14,7 +14,7 @@ class Test<in I, out O> {
|
||||
apply(i)
|
||||
apply(this.i)
|
||||
with(Test<I, O>()) {
|
||||
apply(i) // resolved to this@Test.i
|
||||
apply(<!INVISIBLE_REFERENCE!>i<!>) // K1: this@Test.i, K2: this@with.i, see KT-55446
|
||||
apply(this.<!INVISIBLE_REFERENCE!>i<!>)
|
||||
apply(this@with.<!INVISIBLE_REFERENCE!>i<!>)
|
||||
apply(this@Test.i)
|
||||
|
||||
@@ -14,7 +14,7 @@ class Test<in I, out O> {
|
||||
apply(i)
|
||||
apply(this.i)
|
||||
with(Test<I, O>()) {
|
||||
apply(i) // resolved to this@Test.i
|
||||
apply(i) // K1: this@Test.i, K2: this@with.i, see KT-55446
|
||||
apply(this.<!INVISIBLE_MEMBER("i; private/*private to this*/; 'Test'")!>i<!>)
|
||||
apply(this@with.<!INVISIBLE_MEMBER("i; private/*private to this*/; 'Test'")!>i<!>)
|
||||
apply(this@Test.i)
|
||||
|
||||
@@ -14,7 +14,7 @@ class Test<in I, out O> {
|
||||
i = getT()
|
||||
this.i = getT()
|
||||
with(Test<I, O>()) {
|
||||
i = getT() // resolved to this@Test.i
|
||||
<!INVISIBLE_REFERENCE!>i<!> = getT() // K1: this@Test.i, K2: this@with.i, see KT-55446
|
||||
this.<!INVISIBLE_REFERENCE!>i<!> = getT()
|
||||
this@with.<!INVISIBLE_REFERENCE!>i<!> = getT()
|
||||
this@Test.i = getT()
|
||||
|
||||
@@ -14,7 +14,7 @@ class Test<in I, out O> {
|
||||
i = getT()
|
||||
this.i = getT()
|
||||
with(Test<I, O>()) {
|
||||
i = getT() // resolved to this@Test.i
|
||||
i = getT() // K1: this@Test.i, K2: this@with.i, see KT-55446
|
||||
this.<!INVISIBLE_MEMBER("i; private/*private to this*/; 'Test'")!>i<!> = getT()
|
||||
this@with.<!INVISIBLE_MEMBER("i; private/*private to this*/; 'Test'")!>i<!> = getT()
|
||||
this@Test.i = getT()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// FIR_DUMP
|
||||
|
||||
// explicit types
|
||||
class A<in T>(t: T) {
|
||||
private val t: T = t // PRIVATE_TO_THIS
|
||||
|
||||
@@ -24,3 +25,13 @@ class A<in T>(t: T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// implicit types
|
||||
class C<in T>(t: T) {
|
||||
private val t: T = t
|
||||
private val tt = t
|
||||
|
||||
fun foo(a: C<String>) {
|
||||
val x: String = a.<!INVISIBLE_REFERENCE!>tt<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ FILE: privateToThis.fir.kt
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
private/*private to this*/ final val t: R|T| = R|<local>/t|
|
||||
private/*private to this*/ get(): R|T|
|
||||
private final val t: R|T| = R|<local>/t|
|
||||
private get(): R|T|
|
||||
|
||||
private final val i: R|A.B<T>| = this@R|/A|.R|SubstitutionOverride</A.B.B>|()
|
||||
private get(): R|A.B<T>|
|
||||
@@ -16,11 +16,11 @@ FILE: privateToThis.fir.kt
|
||||
}
|
||||
|
||||
public final fun foo(a: R|A<kotlin/String>|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/String| = R|<local>/a|.R|SubstitutionOverride</A.t: R|kotlin/String|><HIDDEN: /A.t is invisible>#|
|
||||
lval x: R|kotlin/String| = R|<local>/a|.R|SubstitutionOverride</A.t: R|kotlin/String|>|
|
||||
}
|
||||
|
||||
public final fun bar(a: R|A<*>|): R|kotlin/Unit| {
|
||||
R|<local>/a|.R|SubstitutionOverride</A.t: R|CapturedType(*)|><HIDDEN: /A.t is invisible>#|
|
||||
R|<local>/a|.R|SubstitutionOverride</A.t: R|CapturedType(*)|>|
|
||||
}
|
||||
|
||||
public final inner class B<in Outer(T)> : R|kotlin/Any| {
|
||||
@@ -35,3 +35,19 @@ FILE: privateToThis.fir.kt
|
||||
}
|
||||
|
||||
}
|
||||
public final class C<in T> : R|kotlin/Any| {
|
||||
public constructor<in T>(t: R|T|): R|C<T>| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
private final val t: R|T| = R|<local>/t|
|
||||
private get(): R|T|
|
||||
|
||||
private final val tt: R|T| = R|<local>/t|
|
||||
private get(): R|T|
|
||||
|
||||
public final fun foo(a: R|C<kotlin/String>|): R|kotlin/Unit| {
|
||||
lval x: R|kotlin/String| = R|<local>/a|.R|SubstitutionOverride</C.tt: R|kotlin/String|>|
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// FIR_DUMP
|
||||
|
||||
// explicit types
|
||||
class A<in T>(t: T) {
|
||||
private val t: T = t // PRIVATE_TO_THIS
|
||||
|
||||
@@ -24,3 +25,13 @@ class A<in T>(t: T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// implicit types
|
||||
class C<in T>(t: T) {
|
||||
private val t: T = t
|
||||
private val tt = t
|
||||
|
||||
fun foo(a: C<String>) {
|
||||
val x: String = a.<!INVISIBLE_MEMBER!>tt<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,3 +19,14 @@ public final class A</*0*/ in T> {
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
|
||||
public final class C</*0*/ in T> {
|
||||
public constructor C</*0*/ in T>(/*0*/ t: T)
|
||||
private/*private to this*/ final val t: T
|
||||
private/*private to this*/ final val tt: T
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final fun foo(/*0*/ a: C<kotlin.String>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ class Foo<in T> : Base<<!TYPE_VARIANCE_CONFLICT_ERROR!>T<!>>() {
|
||||
|
||||
fun bar(f: Foo<Bar>) {
|
||||
val dnn = f.<!INVISIBLE_REFERENCE!>dnn<!>
|
||||
// This case (and any other with non-denotable type) requires KT-55446 to be fixed
|
||||
val flex = f.flex
|
||||
val flex = f.<!INVISIBLE_REFERENCE!>flex<!>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ class Foo<in T> : Base<<!TYPE_VARIANCE_CONFLICT_ERROR!>T<!>>() {
|
||||
|
||||
fun bar(f: Foo<Bar>) {
|
||||
val dnn = f.<!INVISIBLE_MEMBER!>dnn<!>
|
||||
// This case (and any other with non-denotable type) requires KT-55446 to be fixed
|
||||
val flex = f.<!INVISIBLE_MEMBER!>flex<!>
|
||||
}
|
||||
}
|
||||
|
||||
+11
-11
@@ -1,19 +1,19 @@
|
||||
public final class A<in I> : R|kotlin/Any| {
|
||||
private/*private to this*/ final fun bas(): R|I|
|
||||
private final fun bas(): R|I|
|
||||
|
||||
private/*private to this*/ final val foo: R|I|
|
||||
private/*private to this*/ get(): R|I|
|
||||
private final val foo: R|I|
|
||||
private get(): R|I|
|
||||
|
||||
private/*private to this*/ final var bar: R|I|
|
||||
private/*private to this*/ get(): R|I|
|
||||
private/*private to this*/ set(value: R|I|): R|kotlin/Unit|
|
||||
private final var bar: R|I|
|
||||
private get(): R|I|
|
||||
private set(value: R|I|): R|kotlin/Unit|
|
||||
|
||||
private/*private to this*/ final val val_with_accessors: R|I|
|
||||
private/*private to this*/ get(): R|I|
|
||||
private final val val_with_accessors: R|I|
|
||||
private get(): R|I|
|
||||
|
||||
private/*private to this*/ final var var_with_accessors: R|I|
|
||||
private/*private to this*/ get(): R|I|
|
||||
private/*private to this*/ set(value: R|I|): R|kotlin/Unit|
|
||||
private final var var_with_accessors: R|I|
|
||||
private get(): R|I|
|
||||
private set(value: R|I|): R|kotlin/Unit|
|
||||
|
||||
public constructor<in I>(): R|test/A<I>|
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ object Visibilities {
|
||||
override fun mustCheckInImports(): Boolean = true
|
||||
}
|
||||
|
||||
// K2 doesn't use this visibility, see KT-55446 for details
|
||||
object PrivateToThis : Visibility("private_to_this", isPublicAPI = false) {
|
||||
override val internalDisplayName: String
|
||||
get() = "private/*private to this*/"
|
||||
|
||||
Reference in New Issue
Block a user