[FIR] Fix collecting member candidates on receiver with smartcast

^KT-51460 Fixed
^KT-51827
This commit is contained in:
Dmitriy Novozhilov
2022-04-05 19:21:55 +04:00
committed by teamcity
parent 51bd0fd2db
commit 6e2402620f
29 changed files with 1378 additions and 34 deletions
@@ -25212,6 +25212,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/resolve/resolveWithoutGenerics.kt");
}
@Test
@TestMetadata("smartcastToMoreSpecificProperty.kt")
public void testSmartcastToMoreSpecificProperty() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/smartcastToMoreSpecificProperty.kt");
}
@Test
@TestMetadata("superInvoke.kt")
public void testSuperInvoke() throws Exception {
@@ -28076,6 +28082,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/tests/smartCasts/kt3993.kt");
}
@Test
@TestMetadata("kt51460.kt")
public void testKt51460() throws Exception {
runTest("compiler/testData/diagnostics/tests/smartCasts/kt51460.kt");
}
@Test
@TestMetadata("kt5427.kt")
public void testKt5427() throws Exception {
@@ -32901,6 +32913,30 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
public void testProtectedInternal() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedInternal.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_fakeOverride.kt")
public void testProtectedVisibilityAndSmartcast_fakeOverride() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_fakeOverride.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_noOverride.kt")
public void testProtectedVisibilityAndSmartcast_noOverride() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_noOverride.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_overrideChangesType.kt")
public void testProtectedVisibilityAndSmartcast_overrideChangesType() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_overrideChangesType.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_overrideSameType.kt")
public void testProtectedVisibilityAndSmartcast_overrideSameType() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_overrideSameType.kt");
}
}
@Nested
@@ -25212,6 +25212,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/resolve/resolveWithoutGenerics.kt");
}
@Test
@TestMetadata("smartcastToMoreSpecificProperty.kt")
public void testSmartcastToMoreSpecificProperty() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/smartcastToMoreSpecificProperty.kt");
}
@Test
@TestMetadata("superInvoke.kt")
public void testSuperInvoke() throws Exception {
@@ -28076,6 +28082,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/smartCasts/kt3993.kt");
}
@Test
@TestMetadata("kt51460.kt")
public void testKt51460() throws Exception {
runTest("compiler/testData/diagnostics/tests/smartCasts/kt51460.kt");
}
@Test
@TestMetadata("kt5427.kt")
public void testKt5427() throws Exception {
@@ -32901,6 +32913,30 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
public void testProtectedInternal() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedInternal.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_fakeOverride.kt")
public void testProtectedVisibilityAndSmartcast_fakeOverride() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_fakeOverride.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_noOverride.kt")
public void testProtectedVisibilityAndSmartcast_noOverride() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_noOverride.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_overrideChangesType.kt")
public void testProtectedVisibilityAndSmartcast_overrideChangesType() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_overrideChangesType.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_overrideSameType.kt")
public void testProtectedVisibilityAndSmartcast_overrideSameType() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_overrideSameType.kt");
}
}
@Nested
@@ -25212,6 +25212,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/resolve/resolveWithoutGenerics.kt");
}
@Test
@TestMetadata("smartcastToMoreSpecificProperty.kt")
public void testSmartcastToMoreSpecificProperty() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/smartcastToMoreSpecificProperty.kt");
}
@Test
@TestMetadata("superInvoke.kt")
public void testSuperInvoke() throws Exception {
@@ -28076,6 +28082,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/smartCasts/kt3993.kt");
}
@Test
@TestMetadata("kt51460.kt")
public void testKt51460() throws Exception {
runTest("compiler/testData/diagnostics/tests/smartCasts/kt51460.kt");
}
@Test
@TestMetadata("kt5427.kt")
public void testKt5427() throws Exception {
@@ -32901,6 +32913,30 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
public void testProtectedInternal() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedInternal.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_fakeOverride.kt")
public void testProtectedVisibilityAndSmartcast_fakeOverride() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_fakeOverride.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_noOverride.kt")
public void testProtectedVisibilityAndSmartcast_noOverride() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_noOverride.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_overrideChangesType.kt")
public void testProtectedVisibilityAndSmartcast_overrideChangesType() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_overrideChangesType.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_overrideSameType.kt")
public void testProtectedVisibilityAndSmartcast_overrideSameType() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_overrideSameType.kt");
}
}
@Nested
@@ -1242,7 +1242,7 @@ class Fir2IrDeclarationStorage(
) as IrFunctionSymbol
if (unmatchedReceiver && dispatchReceiverLookupTag is ConeClassLookupTagWithFixedSymbol) {
val originalFunction = originalSymbol.owner as IrSimpleFunction
dispatchReceiverLookupTag.findIrFakeOverride(fir.name, originalFunction) as IrFunctionSymbol
dispatchReceiverLookupTag.findIrFakeOverride(fir.name, originalFunction) as IrFunctionSymbol? ?: originalSymbol
} else {
originalSymbol
}
@@ -16961,6 +16961,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/fakeOverride/diamondFunction.kt");
}
@Test
@TestMetadata("fakeOverrideInAnonymousObject.kt")
public void testFakeOverrideInAnonymousObject() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/fakeOverrideInAnonymousObject.kt");
}
@Test
@TestMetadata("function.kt")
public void testFunction() throws Exception {
@@ -45635,12 +45641,30 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/smartCasts/nullSmartCast.kt");
}
@Test
@TestMetadata("resolveToMemberOfSuperclass_overrideWithDifferentType.kt")
public void testResolveToMemberOfSuperclass_overrideWithDifferentType() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/resolveToMemberOfSuperclass_overrideWithDifferentType.kt");
}
@Test
@TestMetadata("resolveToMemberOfSuperclass_overrideWithSameType.kt")
public void testResolveToMemberOfSuperclass_overrideWithSameType() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/resolveToMemberOfSuperclass_overrideWithSameType.kt");
}
@Test
@TestMetadata("smartCastInsideIf.kt")
public void testSmartCastInsideIf() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/smartCastInsideIf.kt");
}
@Test
@TestMetadata("toStringOnReceiverWIthSmartcast.kt")
public void testToStringOnReceiverWIthSmartcast() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/toStringOnReceiverWIthSmartcast.kt");
}
@Test
@TestMetadata("whenSmartCast.kt")
public void testWhenSmartCast() throws Exception {
@@ -63,10 +63,25 @@ class FirOverrideService(val session: FirSession) : FirSessionComponent {
return result
}
fun <D : FirCallableSymbol<*>> createOverridableGroups(
members: Collection<MemberWithBaseScope<D>>,
overrideChecker: FirOverrideChecker
): List<List<MemberWithBaseScope<D>>> {
if (members.size <= 1) return listOf(members.toList())
val queue = LinkedList(members)
val result = mutableListOf<List<MemberWithBaseScope<D>>>()
while (queue.isNotEmpty()) {
val nextHandle = queue.first()
val overridableGroup = extractBothWaysOverridable(nextHandle, queue, overrideChecker)
result += overridableGroup
}
return result
}
fun <D : FirCallableSymbol<*>> extractBothWaysOverridable(
overrider: MemberWithBaseScope<D>,
members: MutableCollection<MemberWithBaseScope<D>>,
overrideChecker: FirOverrideChecker
overrideChecker: FirOverrideChecker,
): MutableList<MemberWithBaseScope<D>> {
val result = mutableListOf<MemberWithBaseScope<D>>().apply { add(overrider) }
@@ -20,11 +20,12 @@ import org.jetbrains.kotlin.fir.originalIfFakeOverride
fun FirVisibilityChecker.isVisible(
declaration: FirMemberDeclaration,
candidate: Candidate
callInfo: CallInfo,
dispatchReceiverValue: ReceiverValue?
): Boolean {
if (declaration is FirCallableDeclaration && (declaration.isIntersectionOverride || declaration.isSubstitutionOverride)) {
@Suppress("UNCHECKED_CAST")
return isVisible(declaration.originalIfFakeOverride() as FirMemberDeclaration, candidate)
return isVisible(declaration.originalIfFakeOverride() as FirMemberDeclaration, callInfo, dispatchReceiverValue)
}
// We won't resolve into the backing field
@@ -33,18 +34,31 @@ fun FirVisibilityChecker.isVisible(
return true
}
val callInfo = candidate.callInfo
val useSiteFile = callInfo.containingFile
val containingDeclarations = callInfo.containingDeclarations
val session = callInfo.session
val visible = isVisible(
return isVisible(
declaration,
session,
useSiteFile,
containingDeclarations,
candidate.dispatchReceiverValue,
candidate.callInfo.callSite is FirVariableAssignment
dispatchReceiverValue,
callInfo.callSite is FirVariableAssignment
)
}
fun FirVisibilityChecker.isVisible(
declaration: FirMemberDeclaration,
candidate: Candidate
): Boolean {
val callInfo = candidate.callInfo
val visible = isVisible(
declaration,
callInfo,
candidate.dispatchReceiverValue
)
if (visible) {
@@ -52,9 +66,9 @@ fun FirVisibilityChecker.isVisible(
if (backingField != null) {
candidate.hasVisibleBackingField = isVisible(
backingField,
session,
useSiteFile,
containingDeclarations,
callInfo.session,
callInfo.containingFile,
callInfo.containingDeclarations,
candidate.dispatchReceiverValue,
candidate.callInfo.callSite is FirVariableAssignment,
)
@@ -10,19 +10,16 @@ import org.jetbrains.kotlin.fir.declarations.ContextReceiverGroup
import org.jetbrains.kotlin.fir.declarations.FirConstructor
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
import org.jetbrains.kotlin.fir.declarations.utils.isInner
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
import org.jetbrains.kotlin.fir.resolve.typeForQualifier
import org.jetbrains.kotlin.fir.scopes.FirScope
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.scopes.impl.FirDefaultStarImportingScope
import org.jetbrains.kotlin.fir.scopes.impl.FirStandardOverrideChecker
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
@@ -79,13 +76,33 @@ class MemberScopeTowerLevel(
private val scopeSession: ScopeSession get() = bodyResolveComponents.scopeSession
private val session: FirSession get() = bodyResolveComponents.session
private fun <T : FirBasedSymbol<*>> processMembers(
private fun <T : FirCallableSymbol<*>> processMembers(
callInfo: CallInfo,
output: TowerScopeLevelProcessor<T>,
processScopeMembers: FirScope.(processor: (T) -> Unit) -> Unit
): ProcessResult {
val scope = dispatchReceiverValue.scope(session, scopeSession) ?: return ProcessResult.SCOPE_EMPTY
var (empty, candidates) = scope.collectCandidates(processScopeMembers)
consumeCandidates(output, candidates.map { scope to it })
val scopeWithoutSmartcast = (dispatchReceiverValue.receiverExpression as? FirExpressionWithSmartcast)
?.takeIf { it.isStable }
?.originalType
?.coneType
?.scope(session, scopeSession, bodyResolveComponents.returnTypeCalculator.fakeOverrideTypeCalculator)
if (scopeWithoutSmartcast == null) {
consumeCandidates(output, candidates)
} else {
val candidatesFromOriginalType = mutableListOf<MemberWithBaseScope<T>>()
scopeWithoutSmartcast.collectCandidates(processScopeMembers).let { (isEmpty, originalCandidates) ->
empty = empty && isEmpty
candidatesFromOriginalType += originalCandidates
}
if (candidatesFromOriginalType.isNotEmpty()) {
processMembersFromSmartcastedType(callInfo, candidatesFromOriginalType, candidates, output)
} else {
consumeCandidates(output, candidates)
}
}
if (givenExtensionReceiverOptions.isEmpty()) {
val withSynthetic = FirSyntheticPropertiesScope(session, scope)
@@ -97,32 +114,65 @@ class MemberScopeTowerLevel(
return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND
}
private fun <T : FirBasedSymbol<*>> FirTypeScope.collectCandidates(
private fun <T : FirCallableSymbol<*>> processMembersFromSmartcastedType(
callInfo: CallInfo,
candidatesFromOriginalType: Collection<MemberWithBaseScope<T>>,
candidatesFromSmartcast: Collection<MemberWithBaseScope<T>>,
output: TowerScopeLevelProcessor<T>,
) {
val visibilityChecker = session.visibilityChecker
val candidatesMapping = buildMap {
candidatesFromOriginalType.forEach { put(it, false) }
candidatesFromSmartcast.forEach { put(it, true) }
}
val overridableGroups = session.overrideService.createOverridableGroups(
candidatesFromOriginalType + candidatesFromSmartcast,
FirStandardOverrideChecker(session)
)
val candidates = mutableListOf<MemberWithBaseScope<T>>()
for (group in overridableGroups) {
val visibleCandidates = group.filter {
visibilityChecker.isVisible(it.member.fir, callInfo, dispatchReceiverValue)
}
val visibleCandidatesFromSmartcast = visibleCandidates.filter { candidatesMapping.getValue(it) }
if (visibleCandidatesFromSmartcast.isNotEmpty()) {
candidates += visibleCandidatesFromSmartcast
} else {
group.filterNotTo(candidates) { candidatesMapping.getValue(it) }
}
}
consumeCandidates(output, candidates)
}
private fun <T : FirCallableSymbol<*>> FirTypeScope.collectCandidates(
processScopeMembers: FirScope.(processor: (T) -> Unit) -> Unit
): Pair<Boolean, List<T>> {
): Pair<Boolean, List<MemberWithBaseScope<T>>> {
var empty = true
val result = mutableListOf<T>()
val result = mutableListOf<MemberWithBaseScope<T>>()
processScopeMembers { candidate ->
empty = false
if (candidate is FirCallableSymbol<*> && candidate.hasConsistentExtensionReceiver(givenExtensionReceiverOptions)) {
if (candidate.hasConsistentExtensionReceiver(givenExtensionReceiverOptions)) {
val fir = candidate.fir
if ((fir as? FirConstructor)?.isInner == false) {
return@processScopeMembers
}
result += candidate
result += MemberWithBaseScope(candidate, this)
} else if (candidate is FirClassLikeSymbol<*>) {
result += candidate
result += MemberWithBaseScope(candidate, this)
}
}
return empty to result
}
private fun <T : FirBasedSymbol<*>> consumeCandidates(
private fun <T : FirCallableSymbol<*>> consumeCandidates(
output: TowerScopeLevelProcessor<T>,
candidatesWithScope: List<Pair<FirScope, T>>
candidatesWithScope: List<MemberWithBaseScope<T>>
) {
for ((scope, candidate) in candidatesWithScope) {
if (candidate is FirCallableSymbol<*> && candidate.hasConsistentExtensionReceiver(givenExtensionReceiverOptions)) {
for ((candidate, scope) in candidatesWithScope) {
if (candidate.hasConsistentExtensionReceiver(givenExtensionReceiverOptions)) {
output.consumeCandidate(
candidate, dispatchReceiverValue,
givenExtensionReceiverOptions,
@@ -139,7 +189,7 @@ class MemberScopeTowerLevel(
processor: TowerScopeLevelProcessor<FirFunctionSymbol<*>>
): ProcessResult {
val lookupTracker = session.lookupTracker
return processMembers(processor) { consumer ->
return processMembers(info, processor) { consumer ->
withMemberCallLookup(lookupTracker, info) { lookupCtx ->
this.processFunctionsAndConstructorsByName(
info, session, bodyResolveComponents,
@@ -160,13 +210,11 @@ class MemberScopeTowerLevel(
processor: TowerScopeLevelProcessor<FirVariableSymbol<*>>
): ProcessResult {
val lookupTracker = session.lookupTracker
return processMembers(processor) { consumer ->
return processMembers(info, processor) { consumer ->
withMemberCallLookup(lookupTracker, info) { lookupCtx ->
lookupTracker?.recordCallLookup(info, dispatchReceiverValue.type)
this.processPropertiesByName(info.name) {
lookupCtx.recordCallableMemberLookup(it)
// WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF
@Suppress("UNCHECKED_CAST")
consumer(it)
}
}
@@ -0,0 +1,26 @@
// TARGET_BACKEND: JVM_IR
interface JPanel {
val result: String
}
open class ActivePanel : JPanel {
override var result: String = ""
fun fire(event: String) {
result = event
}
}
class Test {
val panel: JPanel
init {
panel = object : ActivePanel() {}
panel.fire("OK")
}
}
fun box(): String {
return Test().panel.result
}
@@ -0,0 +1,32 @@
// TARGET_BACKEND: JVM_IR
// IGNORE_BACKEND: JVM_IR
// ISSUE: KT-51460, KT-51827
open class Base {
protected open val a: CharSequence
get() = "Fail: Base"
fun test(other: Base): String {
return when (other) {
is Derived_1 -> other.a.toString()
is Derived_2 -> other.a.toString()
else -> "Fail: not Derived"
}
}
}
class Derived_1: Base() {
override val a: String
get() = "Fail: Derived_1"
}
class Derived_2: Base() {
override val a: String
get() = "OK"
}
fun box(): String {
val x = Derived_2()
return x.test(x)
}
@@ -0,0 +1,31 @@
// TARGET_BACKEND: JVM_IR
// ISSUE: KT-51460
open class Base {
protected open val a: CharSequence
get() = "Fail: Base"
fun test(other: Base): String {
return when (other) {
is Derived_1 -> other.a.toString()
is Derived_2 -> other.a.toString()
else -> "Fail: not Derived"
}
}
}
class Derived_1: Base() {
override val a: CharSequence
get() = "Fail: Derived_1"
}
class Derived_2: Base() {
override val a: CharSequence
get() = "OK"
}
fun box(): String {
val x = Derived_2()
return x.test(x)
}
@@ -0,0 +1,29 @@
// TARGET_BACKEND: JVM_IR
// FILE: A.java
public class A {
@Override
public String toString() {
return "O";
}
}
// FILE: B.java
public class B {
@Override
public String toString() {
return "K";
}
}
// FILE: main.kt
fun test(x: Any): String {
return when (x) {
is A -> x.toString()
is B -> x.toString()
else -> "fail"
}
}
fun box(): String {
return test(A()) + test(B())
}
@@ -0,0 +1,41 @@
interface A<T : A<T>> {
val symbol: ASymbol<T>
}
interface B<T : B<T>> : A<T> {
override val symbol: BSymbol<T>
}
interface C : B<C> {
fun foo()
override val symbol: CSymbol
}
interface ASymbol<T : A<T>> {
var value: T
}
interface BSymbol<T : B<T>> : ASymbol<T>
interface CSymbol : BSymbol<C> {
fun bar()
}
fun test_1(symbol: BSymbol<*>) {
if (symbol is CSymbol) {
symbol.value.foo()
}
}
fun test_2(b: B<*>) {
if (b is C) {
b.symbol.bar()
}
}
fun <F : B<F>> test_3(b: B<F>) {
if (b is C) {
b.symbol.bar()
}
}
@@ -0,0 +1,41 @@
interface A<T : A<T>> {
val symbol: ASymbol<T>
}
interface B<T : B<T>> : A<T> {
override val symbol: BSymbol<T>
}
interface C : B<C> {
fun foo()
override val symbol: CSymbol
}
interface ASymbol<T : A<T>> {
var value: T
}
interface BSymbol<T : B<T>> : ASymbol<T>
interface CSymbol : BSymbol<C> {
fun bar()
}
fun test_1(symbol: BSymbol<*>) {
if (symbol is CSymbol) {
symbol.value.foo()
}
}
fun test_2(b: B<*>) {
if (b is C) {
b.symbol.bar()
}
}
fun <F : B<F>> test_3(b: B<F>) {
if (b is C) {
<!DEBUG_INFO_SMARTCAST!>b<!>.symbol.bar()
}
}
@@ -0,0 +1,50 @@
package
public fun test_1(/*0*/ symbol: BSymbol<*>): kotlin.Unit
public fun test_2(/*0*/ b: B<*>): kotlin.Unit
public fun </*0*/ F : B<F>> test_3(/*0*/ b: B<F>): kotlin.Unit
public interface A</*0*/ T : A<T>> {
public abstract val symbol: ASymbol<T>
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 interface ASymbol</*0*/ T : A<T>> {
public abstract var value: T
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 interface B</*0*/ T : B<T>> : A<T> {
public abstract override /*1*/ val symbol: BSymbol<T>
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 interface BSymbol</*0*/ T : B<T>> : ASymbol<T> {
public abstract override /*1*/ /*fake_override*/ var value: T
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 interface C : B<C> {
public abstract override /*1*/ val symbol: CSymbol
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract 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 interface CSymbol : BSymbol<C> {
public abstract override /*1*/ /*fake_override*/ var value: C
public abstract fun bar(): kotlin.Unit
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
}
@@ -0,0 +1,18 @@
// FIR_IDENTICAL
// ISSUE: KT-51460
abstract class A {
abstract protected val a: A?
class B(override val a: A?) : A() {
fun f(other: A) {
val x = if (other is C) {
other.a
} else {
null
}
}
}
class C(override val a: A?): A()
}
@@ -0,0 +1,26 @@
package
public abstract class A {
public constructor A()
protected abstract val a: 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
public final class B : A {
public constructor B(/*0*/ a: A?)
protected open override /*1*/ val a: A?
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun f(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class C : A {
public constructor C(/*0*/ a: A?)
protected open override /*1*/ val a: 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
}
}
@@ -0,0 +1,84 @@
// FIR_IDENTICAL
interface Base {
fun baseFun()
}
interface Derived : Base {
fun derivedFun()
}
abstract class A<T : Base> {
protected val a: T = null!!
fun fest_1(other: A<*>) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
other.a.derivedFun()
}
if (other is C) {
other.a.baseFun()
other.a.derivedFun()
}
if (other is D) {
other.a.baseFun()
other.a.derivedFun()
}
}
open class B : A<Derived>() {
class Nested {
fun fest_3(other: A<*>) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
other.a.derivedFun()
}
if (other is C) {
other.a.baseFun()
other.a.derivedFun()
}
if (other is D) {
other.a.baseFun()
other.a.derivedFun()
}
}
}
}
class C : B() {
fun fest_4(other: A<*>) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
other.a.derivedFun()
}
if (other is C) {
other.a.baseFun()
other.a.derivedFun()
}
if (other is D) {
other.a.baseFun()
other.a.derivedFun()
}
}
}
class D : A<Derived>() {
fun fest_5(other: A<*>) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
other.a.derivedFun()
}
if (other is C) {
other.a.baseFun()
other.a.derivedFun()
}
if (other is D) {
other.a.baseFun()
other.a.derivedFun()
}
}
}
}
@@ -0,0 +1,63 @@
package
public abstract class A</*0*/ T : Base> {
public constructor A</*0*/ T : Base>()
protected final val a: T
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun fest_1(/*0*/ other: A<*>): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open class B : A<Derived> {
public constructor B()
protected final override /*1*/ /*fake_override*/ val a: Derived
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun fest_1(/*0*/ other: A<*>): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final class Nested {
public constructor Nested()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun fest_3(/*0*/ other: A<*>): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public final class C : A.B {
public constructor C()
protected final override /*1*/ /*fake_override*/ val a: Derived
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun fest_1(/*0*/ other: A<*>): kotlin.Unit
public final fun fest_4(/*0*/ other: A<*>): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class D : A<Derived> {
public constructor D()
protected final override /*1*/ /*fake_override*/ val a: Derived
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun fest_1(/*0*/ other: A<*>): kotlin.Unit
public final fun fest_5(/*0*/ other: A<*>): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public interface Base {
public abstract fun baseFun(): kotlin.Unit
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 interface Derived : Base {
public abstract override /*1*/ /*fake_override*/ fun baseFun(): kotlin.Unit
public abstract fun derivedFun(): kotlin.Unit
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
}
@@ -0,0 +1,68 @@
// FIR_IDENTICAL
interface Base {
fun baseFun()
}
abstract class A {
protected val a: Base = null!!
fun fest_1(other: A) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
}
if (other is C) {
other.a.baseFun()
}
if (other is D) {
other.a.baseFun()
}
}
open class B : A() {
class Nested {
fun fest_3(other: A) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
}
if (other is C) {
other.a.baseFun()
}
if (other is D) {
other.a.baseFun()
}
}
}
}
class C : B() {
fun fest_4(other: A) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
}
if (other is C) {
other.a.baseFun()
}
if (other is D) {
other.a.baseFun()
}
}
}
class D : A() {
fun fest_5(other: A) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
}
if (other is C) {
other.a.baseFun()
}
if (other is D) {
other.a.baseFun()
}
}
}
}
@@ -0,0 +1,55 @@
package
public abstract class A {
public constructor A()
protected final val a: Base
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun fest_1(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open class B : A {
public constructor B()
protected final override /*1*/ /*fake_override*/ val a: Base
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun fest_1(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final class Nested {
public constructor Nested()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun fest_3(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public final class C : A.B {
public constructor C()
protected final override /*1*/ /*fake_override*/ val a: Base
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun fest_1(/*0*/ other: A): kotlin.Unit
public final fun fest_4(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class D : A {
public constructor D()
protected final override /*1*/ /*fake_override*/ val a: Base
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun fest_1(/*0*/ other: A): kotlin.Unit
public final fun fest_5(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public interface Base {
public abstract fun baseFun(): kotlin.Unit
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
}
@@ -0,0 +1,85 @@
// FIR_DUMP
interface Base {
fun baseFun()
}
interface Derived : Base {
fun derivedFun()
}
abstract class A {
abstract protected val a: Base
fun fest_1(other: A) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
other.a.<!UNRESOLVED_REFERENCE!>derivedFun<!>()
}
if (other is C) {
other.a.baseFun()
other.a.<!UNRESOLVED_REFERENCE!>derivedFun<!>()
}
if (other is D) {
other.a.baseFun()
other.a.<!UNRESOLVED_REFERENCE!>derivedFun<!>()
}
}
open class B(override val a: Derived) : A() {
class Nested {
fun fest_3(other: A) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
other.a.derivedFun()
}
if (other is C) {
other.a.baseFun()
other.a.<!UNRESOLVED_REFERENCE!>derivedFun<!>()
}
if (other is D) {
other.a.baseFun()
other.a.<!UNRESOLVED_REFERENCE!>derivedFun<!>()
}
}
}
}
class C(override val a: Derived) : B(a) {
fun fest_4(other: A) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
other.a.<!UNRESOLVED_REFERENCE!>derivedFun<!>()
}
if (other is C) {
other.a.baseFun()
other.a.derivedFun()
}
if (other is D) {
other.a.baseFun()
other.a.<!UNRESOLVED_REFERENCE!>derivedFun<!>()
}
}
}
class D(override val a: Derived) : A() {
fun fest_5(other: A) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
other.a.<!UNRESOLVED_REFERENCE!>derivedFun<!>()
}
if (other is C) {
other.a.baseFun()
other.a.<!UNRESOLVED_REFERENCE!>derivedFun<!>()
}
if (other is D) {
other.a.baseFun()
other.a.derivedFun()
}
}
}
}
@@ -0,0 +1,155 @@
FILE: protectedVisibilityAndSmartcast_overrideChangesType.fir.kt
public abstract interface Base : R|kotlin/Any| {
public abstract fun baseFun(): R|kotlin/Unit|
}
public abstract interface Derived : R|Base| {
public abstract fun derivedFun(): R|kotlin/Unit|
}
public abstract class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
protected abstract val a: R|Base|
protected get(): R|Base|
public final fun fest_1(other: R|A|): R|kotlin/Unit| {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
when () {
(R|<local>/other| is R|A.B|) -> {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
R|<local>/other|.R|/A.a|.<Unresolved name: derivedFun>#()
}
}
when () {
(R|<local>/other| is R|A.C|) -> {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
R|<local>/other|.R|/A.a|.<Unresolved name: derivedFun>#()
}
}
when () {
(R|<local>/other| is R|A.D|) -> {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
R|<local>/other|.R|/A.a|.<Unresolved name: derivedFun>#()
}
}
}
public open class B : R|A| {
public constructor(a: R|Derived|): R|A.B| {
super<R|A|>()
}
protected open override val a: R|Derived| = R|<local>/a|
protected get(): R|Derived|
public final class Nested : R|kotlin/Any| {
public constructor(): R|A.B.Nested| {
super<R|kotlin/Any|>()
}
public final fun fest_3(other: R|A|): R|kotlin/Unit| {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
when () {
(R|<local>/other| is R|A.B|) -> {
R|<local>/other|.R|/A.B.a|.R|/Base.baseFun|()
R|<local>/other|.R|/A.B.a|.R|/Derived.derivedFun|()
}
}
when () {
(R|<local>/other| is R|A.C|) -> {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
R|<local>/other|.R|/A.a|.<Unresolved name: derivedFun>#()
}
}
when () {
(R|<local>/other| is R|A.D|) -> {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
R|<local>/other|.R|/A.a|.<Unresolved name: derivedFun>#()
}
}
}
}
}
public final class C : R|A.B| {
public constructor(a: R|Derived|): R|A.C| {
super<R|A.B|>(R|<local>/a|)
}
protected final override val a: R|Derived| = R|<local>/a|
protected get(): R|Derived|
public final fun fest_4(other: R|A|): R|kotlin/Unit| {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
when () {
(R|<local>/other| is R|A.B|) -> {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
R|<local>/other|.R|/A.a|.<Unresolved name: derivedFun>#()
}
}
when () {
(R|<local>/other| is R|A.C|) -> {
R|<local>/other|.R|/A.C.a|.R|/Base.baseFun|()
R|<local>/other|.R|/A.C.a|.R|/Derived.derivedFun|()
}
}
when () {
(R|<local>/other| is R|A.D|) -> {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
R|<local>/other|.R|/A.a|.<Unresolved name: derivedFun>#()
}
}
}
}
public final class D : R|A| {
public constructor(a: R|Derived|): R|A.D| {
super<R|A|>()
}
protected final override val a: R|Derived| = R|<local>/a|
protected get(): R|Derived|
public final fun fest_5(other: R|A|): R|kotlin/Unit| {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
when () {
(R|<local>/other| is R|A.B|) -> {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
R|<local>/other|.R|/A.a|.<Unresolved name: derivedFun>#()
}
}
when () {
(R|<local>/other| is R|A.C|) -> {
R|<local>/other|.R|/A.a|.R|/Base.baseFun|()
R|<local>/other|.R|/A.a|.<Unresolved name: derivedFun>#()
}
}
when () {
(R|<local>/other| is R|A.D|) -> {
R|<local>/other|.R|/A.D.a|.R|/Base.baseFun|()
R|<local>/other|.R|/A.D.a|.R|/Derived.derivedFun|()
}
}
}
}
}
@@ -0,0 +1,85 @@
// FIR_DUMP
interface Base {
fun baseFun()
}
interface Derived : Base {
fun derivedFun()
}
abstract class A {
abstract protected val a: Base
fun fest_1(other: A) {
other.a.baseFun() // OK
if (other is B) {
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.baseFun()
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.derivedFun()
}
if (other is C) {
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.baseFun()
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.derivedFun()
}
if (other is D) {
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.baseFun()
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.derivedFun()
}
}
open class B(override val a: Derived) : A() {
class Nested {
fun fest_3(other: A) {
other.a.baseFun() // OK
if (other is B) {
<!DEBUG_INFO_SMARTCAST!>other<!>.a.baseFun()
<!DEBUG_INFO_SMARTCAST!>other<!>.a.derivedFun()
}
if (other is C) {
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.baseFun()
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.derivedFun()
}
if (other is D) {
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.baseFun()
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.derivedFun()
}
}
}
}
class C(override val a: Derived) : B(a) {
fun fest_4(other: A) {
other.a.baseFun() // OK
if (other is B) {
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.baseFun()
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.derivedFun()
}
if (other is C) {
<!DEBUG_INFO_SMARTCAST!>other<!>.a.baseFun()
<!DEBUG_INFO_SMARTCAST!>other<!>.a.derivedFun()
}
if (other is D) {
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.baseFun()
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.derivedFun()
}
}
}
class D(override val a: Derived) : A() {
fun fest_5(other: A) {
other.a.baseFun() // OK
if (other is B) {
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.baseFun()
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.derivedFun()
}
if (other is C) {
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.baseFun()
<!DEBUG_INFO_SMARTCAST!>other<!>.<!INVISIBLE_MEMBER!>a<!>.derivedFun()
}
if (other is D) {
<!DEBUG_INFO_SMARTCAST!>other<!>.a.baseFun()
<!DEBUG_INFO_SMARTCAST!>other<!>.a.derivedFun()
}
}
}
}
@@ -0,0 +1,63 @@
package
public abstract class A {
public constructor A()
protected abstract val a: Base
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun fest_1(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open class B : A {
public constructor B(/*0*/ a: Derived)
protected open override /*1*/ val a: Derived
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun fest_1(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final class Nested {
public constructor Nested()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun fest_3(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public final class C : A.B {
public constructor C(/*0*/ a: Derived)
protected open override /*1*/ val a: Derived
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun fest_1(/*0*/ other: A): kotlin.Unit
public final fun fest_4(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class D : A {
public constructor D(/*0*/ a: Derived)
protected open override /*1*/ val a: Derived
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun fest_1(/*0*/ other: A): kotlin.Unit
public final fun fest_5(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public interface Base {
public abstract fun baseFun(): kotlin.Unit
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 interface Derived : Base {
public abstract override /*1*/ /*fake_override*/ fun baseFun(): kotlin.Unit
public abstract fun derivedFun(): kotlin.Unit
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
}
@@ -0,0 +1,68 @@
// FIR_IDENTICAL
interface Base {
fun baseFun()
}
abstract class A {
abstract protected val a: Base
fun fest_1(other: A) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
}
if (other is C) {
other.a.baseFun()
}
if (other is D) {
other.a.baseFun()
}
}
open class B(override val a: Base) : A() {
class Nested {
fun fest_3(other: A) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
}
if (other is C) {
other.a.baseFun()
}
if (other is D) {
other.a.baseFun()
}
}
}
}
class C(override val a: Base) : B(a) {
fun fest_4(other: A) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
}
if (other is C) {
other.a.baseFun()
}
if (other is D) {
other.a.baseFun()
}
}
}
class D(override val a: Base) : A() {
fun fest_5(other: A) {
other.a.baseFun() // OK
if (other is B) {
other.a.baseFun()
}
if (other is C) {
other.a.baseFun()
}
if (other is D) {
other.a.baseFun()
}
}
}
}
@@ -0,0 +1,55 @@
package
public abstract class A {
public constructor A()
protected abstract val a: Base
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun fest_1(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public open class B : A {
public constructor B(/*0*/ a: Base)
protected open override /*1*/ val a: Base
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun fest_1(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final class Nested {
public constructor Nested()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final fun fest_3(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public final class C : A.B {
public constructor C(/*0*/ a: Base)
protected open override /*1*/ val a: Base
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun fest_1(/*0*/ other: A): kotlin.Unit
public final fun fest_4(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class D : A {
public constructor D(/*0*/ a: Base)
protected open override /*1*/ val a: Base
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public final override /*1*/ /*fake_override*/ fun fest_1(/*0*/ other: A): kotlin.Unit
public final fun fest_5(/*0*/ other: A): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public interface Base {
public abstract fun baseFun(): kotlin.Unit
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
}
@@ -25224,6 +25224,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/resolve/resolveWithoutGenerics.kt");
}
@Test
@TestMetadata("smartcastToMoreSpecificProperty.kt")
public void testSmartcastToMoreSpecificProperty() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/smartcastToMoreSpecificProperty.kt");
}
@Test
@TestMetadata("superInvoke.kt")
public void testSuperInvoke() throws Exception {
@@ -28166,6 +28172,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/smartCasts/kt3993.kt");
}
@Test
@TestMetadata("kt51460.kt")
public void testKt51460() throws Exception {
runTest("compiler/testData/diagnostics/tests/smartCasts/kt51460.kt");
}
@Test
@TestMetadata("kt5427.kt")
public void testKt5427() throws Exception {
@@ -32991,6 +33003,30 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
public void testProtectedInternal() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedInternal.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_fakeOverride.kt")
public void testProtectedVisibilityAndSmartcast_fakeOverride() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_fakeOverride.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_noOverride.kt")
public void testProtectedVisibilityAndSmartcast_noOverride() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_noOverride.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_overrideChangesType.kt")
public void testProtectedVisibilityAndSmartcast_overrideChangesType() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_overrideChangesType.kt");
}
@Test
@TestMetadata("protectedVisibilityAndSmartcast_overrideSameType.kt")
public void testProtectedVisibilityAndSmartcast_overrideSameType() throws Exception {
runTest("compiler/testData/diagnostics/tests/visibility/protectedVisibilityAndSmartcast_overrideSameType.kt");
}
}
@Nested
@@ -16961,6 +16961,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/fakeOverride/diamondFunction.kt");
}
@Test
@TestMetadata("fakeOverrideInAnonymousObject.kt")
public void testFakeOverrideInAnonymousObject() throws Exception {
runTest("compiler/testData/codegen/box/fakeOverride/fakeOverrideInAnonymousObject.kt");
}
@Test
@TestMetadata("function.kt")
public void testFunction() throws Exception {
@@ -45635,12 +45641,30 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/smartCasts/nullSmartCast.kt");
}
@Test
@TestMetadata("resolveToMemberOfSuperclass_overrideWithDifferentType.kt")
public void testResolveToMemberOfSuperclass_overrideWithDifferentType() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/resolveToMemberOfSuperclass_overrideWithDifferentType.kt");
}
@Test
@TestMetadata("resolveToMemberOfSuperclass_overrideWithSameType.kt")
public void testResolveToMemberOfSuperclass_overrideWithSameType() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/resolveToMemberOfSuperclass_overrideWithSameType.kt");
}
@Test
@TestMetadata("smartCastInsideIf.kt")
public void testSmartCastInsideIf() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/smartCastInsideIf.kt");
}
@Test
@TestMetadata("toStringOnReceiverWIthSmartcast.kt")
public void testToStringOnReceiverWIthSmartcast() throws Exception {
runTest("compiler/testData/codegen/box/smartCasts/toStringOnReceiverWIthSmartcast.kt");
}
@Test
@TestMetadata("whenSmartCast.kt")
public void testWhenSmartCast() throws Exception {