diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt index 6cfd31f881d..97fd133c9a6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.CandidateFactory import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind +import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability internal class CandidateFactoriesAndCollectors( // Common calls @@ -85,8 +86,8 @@ private class TowerScopeLevelProcessor( scope: FirScope, objectsByName: Boolean, isFromOriginalTypeInPresenceOfSmartCast: Boolean, - ) { - resultCollector.consumeCandidate( + ): CandidateApplicability { + return resultCollector.consumeCandidate( group, candidateFactory.createCandidate( callInfo, symbol, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt index 7e08bf42525..4aa4528963a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirImplicitAnyTypeRef import org.jetbrains.kotlin.fir.utils.exceptions.withConeTypeEntry import org.jetbrains.kotlin.name.StandardClassIds.Annotations.HidesMembers +import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment @@ -59,7 +60,7 @@ abstract class TowerScopeLevel { scope: FirScope, objectsByName: Boolean = false, isFromOriginalTypeInPresenceOfSmartCast: Boolean = false, - ) + ): CandidateApplicability } } @@ -86,14 +87,13 @@ class MemberScopeTowerLevel( val scope = dispatchReceiverValue.scope(session, scopeSession) ?: return ProcessResult.SCOPE_EMPTY var (empty, candidates) = scope.collectCandidates(processScopeMembers) - val scopeWithoutSmartcast = getOriginalReceiverExpressionIfStableSmartCast() - ?.resolvedType - ?.scope( - session, - scopeSession, - bodyResolveComponents.returnTypeCalculator.callableCopyTypeCalculator, - requiredMembersPhase = FirResolvePhase.STATUS, - ) + val receiverTypeWithoutSmartCast = getOriginalReceiverExpressionIfStableSmartCast()?.resolvedType + val scopeWithoutSmartcast = receiverTypeWithoutSmartCast?.scope( + session, + scopeSession, + bodyResolveComponents.returnTypeCalculator.callableCopyTypeCalculator, + requiredMembersPhase = FirResolvePhase.STATUS, + ) if (scopeWithoutSmartcast == null) { consumeCandidates( @@ -107,12 +107,22 @@ class MemberScopeTowerLevel( scopeWithoutSmartcast.collectCandidates(processScopeMembers).let { (isEmpty, originalCandidates) -> empty = empty && isEmpty for (originalCandidate in originalCandidates) { - map[originalCandidate.member] = MemberFromSmartcastScope(originalCandidate, cameFromSmartcast = false) + map[originalCandidate.member] = MemberFromSmartcastScope(originalCandidate, DispatchReceiverToUse.UnwrapSmartcast) } } for (candidateFromSmartCast in candidates) { - map[candidateFromSmartCast.member] = MemberFromSmartcastScope(candidateFromSmartCast, cameFromSmartcast = true) + val existing = map[candidateFromSmartCast.member] + + // If both scopes return the same symbol, we want to prefer the candidate from the original scope without smartcast + // with two exceptions: + // - When the smart-casted type is always null, we want to return it and report UNSAFE_CALL. + // - When the original type can be null, in this case the smart-case either makes it not-null or the call is red anyway. + if (existing == null || dispatchReceiverValue.type.isNullableNothing || receiverTypeWithoutSmartCast.canBeNull) { + map[candidateFromSmartCast.member] = MemberFromSmartcastScope(candidateFromSmartCast, DispatchReceiverToUse.SmartcastWithoutUnwrapping) + } else { + existing.dispatchReceiverToUse = DispatchReceiverToUse.SmartcastIfUnwrappedInvisible + } } consumeCandidates( @@ -170,9 +180,15 @@ class MemberScopeTowerLevel( return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND } - private data class MemberFromSmartcastScope>( + private enum class DispatchReceiverToUse(val unwrapSmartcast: Boolean) { + UnwrapSmartcast(true), + SmartcastWithoutUnwrapping(false), + SmartcastIfUnwrappedInvisible(true), + } + + private class MemberFromSmartcastScope>( val memberWithBaseScope: MemberWithBaseScope, - val cameFromSmartcast: Boolean + var dispatchReceiverToUse: DispatchReceiverToUse, ) private fun > FirTypeScope.collectCandidates( @@ -208,13 +224,11 @@ class MemberScopeTowerLevel( ?: candidatesWithSmartcast?.values?.map { it.memberWithBaseScope } ?: error("candidatesWithoutSmartcast or candidatesWithSmartcast should be not null") - for (candidateWithScope in candidates) { - val (candidate, scope) = candidateWithScope + for ((candidate, scope) in candidates) { if (candidate.hasConsistentExtensionReceiver(givenExtensionReceiverOptions)) { - val isFromOriginalTypeInPresenceOfSmartCast = candidatesWithSmartcast != null && - !candidatesWithSmartcast.getValue(candidateWithScope.member).cameFromSmartcast - - val dispatchReceiverToUse = when { + val dispatchReceiverToUse = candidatesWithSmartcast?.getValue(candidate)?.dispatchReceiverToUse + val isFromOriginalTypeInPresenceOfSmartCast = dispatchReceiverToUse?.unwrapSmartcast == true + val dispatchReceiver = when { isFromOriginalTypeInPresenceOfSmartCast -> getOriginalReceiverExpressionIfStableSmartCast() // For a chain inference stub in dispatch receiver, we have to provide an explicit cast to Any @@ -229,13 +243,23 @@ class MemberScopeTowerLevel( else -> dispatchReceiverValue.receiverExpression } - output.consumeCandidate( + val applicability = output.consumeCandidate( candidate, - dispatchReceiverToUse, + dispatchReceiver, givenExtensionReceiverOptions, scope, isFromOriginalTypeInPresenceOfSmartCast = isFromOriginalTypeInPresenceOfSmartCast ) + + if (applicability == CandidateApplicability.K2_VISIBILITY_ERROR && dispatchReceiverToUse == DispatchReceiverToUse.SmartcastIfUnwrappedInvisible) { + output.consumeCandidate( + candidate, + dispatchReceiverValue.receiverExpression, + givenExtensionReceiverOptions, + scope, + isFromOriginalTypeInPresenceOfSmartCast = false + ) + } } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt index 0186e145fb7..950e6d193ac 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirCallCompletionResultsWriterTransformer.kt @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.resolve.calls.inference.model.InferredEmptyIntersection +import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tower.isSuccess import org.jetbrains.kotlin.types.TypeApproximatorConfiguration import org.jetbrains.kotlin.types.Variance @@ -140,6 +141,18 @@ class FirCallCompletionResultsWriterTransformer( replaceCalleeReference(calleeReference.toResolvedReference()) replaceDispatchReceiver(dispatchReceiver) replaceExtensionReceiver(extensionReceiver) + + // If the explicit receiver is a smartcast expression, we can choose to use the unwrapped expression as dispatch receiver. + // To maintain the invariant + // explicitReceiver != null => explicitReceiver == dispatchReceiver || explicitReceiver == extensionReceiver + // we update the explicit receiver here. + // We only do this if the candidate is successful, otherwise, we can lose the explicit receiver node in red code like + // fun f(s: String, action: (String.() -> Unit)?) { + // s.action?.let { it() } + //} + if (subCandidate.explicitReceiverKind == ExplicitReceiverKind.DISPATCH_RECEIVER && subCandidate.applicability.isSuccess) { + replaceExplicitReceiver(dispatchReceiver) + } } qualifiedAccessExpression.replaceContextReceiverArguments(subCandidate.contextReceiverArguments()) diff --git a/compiler/testData/codegen/box/smartCasts/propertyInitializationAfterSmartCast.fir.ir.txt b/compiler/testData/codegen/box/smartCasts/propertyInitializationAfterSmartCast.fir.ir.txt index ede052cc495..5507693065c 100644 --- a/compiler/testData/codegen/box/smartCasts/propertyInitializationAfterSmartCast.fir.ir.txt +++ b/compiler/testData/codegen/box/smartCasts/propertyInitializationAfterSmartCast.fir.ir.txt @@ -29,12 +29,10 @@ FILE fqName: fileName:/propertyInitializationAfterSmartCast.kt TYPE_OP type=.Derived_1 origin=CAST typeOperand=.Derived_1 GET_VAR ': .Base_1 declared in .Base_1' type=.Base_1 origin=null SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Any? visibility:private [final]' type=kotlin.Unit origin=null - receiver: TYPE_OP type=.Derived_1 origin=IMPLICIT_CAST typeOperand=.Derived_1 - GET_VAR ': .Base_1 declared in .Base_1' type=.Base_1 origin=null + receiver: GET_VAR ': .Base_1 declared in .Base_1' type=.Base_1 origin=null value: CONST String type=kotlin.String value="O" SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Any? visibility:private [final]' type=kotlin.Unit origin=null - receiver: TYPE_OP type=.Derived_1 origin=IMPLICIT_CAST typeOperand=.Derived_1 - GET_VAR ': .Base_1 declared in .Base_1' type=.Base_1 origin=null + receiver: GET_VAR ': .Base_1 declared in .Base_1' type=.Base_1 origin=null value: CONST String type=kotlin.String value="O" FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: @@ -114,12 +112,10 @@ FILE fqName: fileName:/propertyInitializationAfterSmartCast.kt TYPE_OP type=.Impl_2 origin=CAST typeOperand=.Impl_2 GET_VAR ': .Base_2 declared in .Base_2' type=.Base_2 origin=null SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Any? visibility:private [final]' type=kotlin.Unit origin=null - receiver: TYPE_OP type=.Impl_2 origin=IMPLICIT_CAST typeOperand=.Impl_2 - GET_VAR ': .Base_2 declared in .Base_2' type=.Base_2 origin=null + receiver: GET_VAR ': .Base_2 declared in .Base_2' type=.Base_2 origin=null value: CONST String type=kotlin.String value="K" SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:y type:kotlin.Any? visibility:private [final]' type=kotlin.Unit origin=null - receiver: TYPE_OP type=.Impl_2 origin=IMPLICIT_CAST typeOperand=.Impl_2 - GET_VAR ': .Base_2 declared in .Base_2' type=.Base_2 origin=null + receiver: GET_VAR ': .Base_2 declared in .Base_2' type=.Base_2 origin=null value: CONST String type=kotlin.String value="K" FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: diff --git a/compiler/testData/codegen/bytecodeText/falseSmartCast.kt b/compiler/testData/codegen/bytecodeText/falseSmartCast.kt index 9f35aead501..a839cfa3870 100644 --- a/compiler/testData/codegen/bytecodeText/falseSmartCast.kt +++ b/compiler/testData/codegen/bytecodeText/falseSmartCast.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND_K2: JVM_IR - open class SuperFoo { public fun bar() { if (this is Foo) { diff --git a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.fir.kt b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.fir.kt index 3faa2c70851..8905522845a 100644 --- a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.fir.kt +++ b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.fir.kt @@ -27,4 +27,21 @@ class Derived : Base() { x.y = x.y + 1 } } + + protected fun baz2(x: Base?) { + x.foo() + x.bar() + + x.x = x.x + 1 + x.y = x.y + 1 + + if (x is Derived) { + x.foo() + x.bar() + x.baz(x) + + x.x = x.x + 1 + x.y = x.y + 1 + } + } } diff --git a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.kt b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.kt index e796f0c82c3..8b6aaa63937 100644 --- a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.kt +++ b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.kt @@ -27,4 +27,21 @@ class Derived : Base() { x.y = x.y + 1 } } + + protected fun baz2(x: Base?) { + x.foo() + x.bar() + + x.x = x.x + 1 + x.y = x.y + 1 + + if (x is Derived) { + x.foo() + x.bar() + x.baz(x) + + x.x = x.x + 1 + x.y = x.y + 1 + } + } } diff --git a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.txt b/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.txt deleted file mode 100644 index 1ed29e90330..00000000000 --- a/compiler/testData/diagnostics/tests/scopes/protectedVisibility/withSmartcast.txt +++ /dev/null @@ -1,24 +0,0 @@ -package - -public open class Base { - public constructor Base() - protected open var x: kotlin.Int - public open var y: kotlin.Int - protected open fun bar(): kotlin.Unit - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - protected 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 -} - -public final class Derived : Base { - public constructor Derived() - protected open override /*1*/ /*fake_override*/ var x: kotlin.Int - public open override /*1*/ /*fake_override*/ var y: kotlin.Int - protected open override /*1*/ fun bar(): kotlin.Unit - protected final fun baz(/*0*/ x: Base): kotlin.Unit - public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean - protected open override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit - public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int - public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String -} diff --git a/compiler/testData/diagnostics/tests/when/deprecatedSyntaxInConditionsNoSubject.fir.kt b/compiler/testData/diagnostics/tests/when/deprecatedSyntaxInConditionsNoSubject.fir.kt index ebec5dd553d..a9453ba09a4 100644 --- a/compiler/testData/diagnostics/tests/when/deprecatedSyntaxInConditionsNoSubject.fir.kt +++ b/compiler/testData/diagnostics/tests/when/deprecatedSyntaxInConditionsNoSubject.fir.kt @@ -41,10 +41,10 @@ fun testWithSubject_ok(x: Boolean, y: Boolean?, any: Any, z: Boolean) { x !in x -> {} x is String -> {} x !is String -> {} - x < x -> {} - x > x -> {} - x <= x -> {} - x >= x -> {} + x < x -> {} + x > x -> {} + x <= x -> {} + x >= x -> {} x == x -> {} x != x -> {} x === x -> {} diff --git a/compiler/testData/ir/irText/classes/smartCastInValInitialization.fir.ir.txt b/compiler/testData/ir/irText/classes/smartCastInValInitialization.fir.ir.txt deleted file mode 100644 index cf7f3a9cf7d..00000000000 --- a/compiler/testData/ir/irText/classes/smartCastInValInitialization.fir.ir.txt +++ /dev/null @@ -1,65 +0,0 @@ -FILE fqName: fileName:/smartCastInValInitialization.kt - CLASS CLASS name:RootBus modality:FINAL visibility:public superTypes:[.MessageBusImpl] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.RootBus - CONSTRUCTOR visibility:public <> () returnType:.RootBus [primary] - BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in .MessageBusImpl' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:RootBus modality:FINAL visibility:public superTypes:[.MessageBusImpl]' - PROPERTY FAKE_OVERRIDE name:parentBus visibility:public modality:FINAL [fake_override,val] - overridden: - public final parentBus: kotlin.Any? - FUN FAKE_OVERRIDE name: visibility:public modality:FINAL <> ($this:.MessageBusImpl) returnType:kotlin.Any? [fake_override] - correspondingProperty: PROPERTY FAKE_OVERRIDE name:parentBus visibility:public modality:FINAL [fake_override,val] - overridden: - public final fun (): kotlin.Any? declared in .MessageBusImpl - $this: VALUE_PARAMETER name: type:.MessageBusImpl - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .MessageBusImpl - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in .MessageBusImpl - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in .MessageBusImpl - $this: VALUE_PARAMETER name: type:kotlin.Any - CLASS CLASS name:MessageBusImpl modality:OPEN visibility:public superTypes:[kotlin.Any] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.MessageBusImpl - CONSTRUCTOR visibility:public <> () returnType:.MessageBusImpl [primary] - BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:MessageBusImpl modality:OPEN visibility:public superTypes:[kotlin.Any]' - PROPERTY name:parentBus visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:parentBus type:kotlin.Any? visibility:private [final] - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.MessageBusImpl) returnType:kotlin.Any? - correspondingProperty: PROPERTY name:parentBus visibility:public modality:FINAL [val] - $this: VALUE_PARAMETER name: type:.MessageBusImpl - BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.Any? declared in .MessageBusImpl' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:parentBus type:kotlin.Any? visibility:private [final]' type=kotlin.Any? origin=null - receiver: GET_VAR ': .MessageBusImpl declared in .MessageBusImpl.' type=.MessageBusImpl origin=null - ANONYMOUS_INITIALIZER isStatic=false - BLOCK_BODY - TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - TYPE_OP type=.RootBus origin=CAST typeOperand=.RootBus - GET_VAR ': .MessageBusImpl declared in .MessageBusImpl' type=.MessageBusImpl origin=null - SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:parentBus type:kotlin.Any? visibility:private [final]' type=kotlin.Unit origin=null - receiver: TYPE_OP type=.RootBus origin=IMPLICIT_CAST typeOperand=.RootBus - GET_VAR ': .MessageBusImpl declared in .MessageBusImpl' type=.MessageBusImpl origin=null - value: CONST Null type=kotlin.Nothing? value=null - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/testData/ir/irText/classes/smartCastInValInitialization.fir.kt.txt b/compiler/testData/ir/irText/classes/smartCastInValInitialization.fir.kt.txt deleted file mode 100644 index f2c17e59e3c..00000000000 --- a/compiler/testData/ir/irText/classes/smartCastInValInitialization.fir.kt.txt +++ /dev/null @@ -1,25 +0,0 @@ -class RootBus : MessageBusImpl { - constructor() /* primary */ { - super/*MessageBusImpl*/() - /* () */ - - } - -} - -open class MessageBusImpl { - constructor() /* primary */ { - super/*Any*/() - /* () */ - - } - - val parentBus: Any? - get - - init { - as RootBus /*~> Unit */ - /*as RootBus */.#parentBus = null - } - -} diff --git a/compiler/testData/ir/irText/classes/smartCastInValInitialization.kt b/compiler/testData/ir/irText/classes/smartCastInValInitialization.kt index 39cec492f95..d7aa58fe018 100644 --- a/compiler/testData/ir/irText/classes/smartCastInValInitialization.kt +++ b/compiler/testData/ir/irText/classes/smartCastInValInitialization.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL class RootBus: MessageBusImpl() open class MessageBusImpl { diff --git a/compiler/testData/ir/irText/expressions/smartCastAside.fir.ir.txt b/compiler/testData/ir/irText/expressions/smartCastAside.fir.ir.txt deleted file mode 100644 index 39db290b85a..00000000000 --- a/compiler/testData/ir/irText/expressions/smartCastAside.fir.ir.txt +++ /dev/null @@ -1,76 +0,0 @@ -FILE fqName: fileName:/smartCastAside.kt - CLASS INTERFACE name:A modality:ABSTRACT visibility:public superTypes:[kotlin.Any] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.A - FUN name:foo visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit - $this: VALUE_PARAMETER name: type:.A - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - CLASS INTERFACE name:B modality:ABSTRACT visibility:public superTypes:[.A] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.B - FUN name:bar visibility:public modality:ABSTRACT <> ($this:.B) returnType:kotlin.Unit - $this: VALUE_PARAMETER name: type:.B - FUN FAKE_OVERRIDE name:foo visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit [fake_override] - overridden: - public abstract fun foo (): kotlin.Unit declared in .A - $this: VALUE_PARAMETER name: type:.A - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .A - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in .A - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in .A - $this: VALUE_PARAMETER name: type:kotlin.Any - CLASS INTERFACE name:C modality:ABSTRACT visibility:public superTypes:[.A] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C - FUN name:baz visibility:public modality:ABSTRACT <> ($this:.C) returnType:kotlin.Unit - $this: VALUE_PARAMETER name: type:.C - FUN FAKE_OVERRIDE name:foo visibility:public modality:ABSTRACT <> ($this:.A) returnType:kotlin.Unit [fake_override] - overridden: - public abstract fun foo (): kotlin.Unit declared in .A - $this: VALUE_PARAMETER name: type:.A - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .A - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in .A - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in .A - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN name:test visibility:public modality:FINAL <> (param:.B) returnType:kotlin.Unit - VALUE_PARAMETER name:param index:0 type:.B - BLOCK_BODY - WHEN type=kotlin.Unit origin=IF - BRANCH - if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.C - GET_VAR 'param: .B declared in .test' type=.B origin=null - then: BLOCK type=kotlin.Unit origin=null - CALL 'public abstract fun foo (): kotlin.Unit declared in .A' type=kotlin.Unit origin=null - $this: TYPE_OP type=.C origin=IMPLICIT_CAST typeOperand=.C - GET_VAR 'param: .B declared in .test' type=.B origin=null - CALL 'public abstract fun bar (): kotlin.Unit declared in .B' type=kotlin.Unit origin=null - $this: GET_VAR 'param: .B declared in .test' type=.B origin=null - CALL 'public abstract fun baz (): kotlin.Unit declared in .C' type=kotlin.Unit origin=null - $this: TYPE_OP type=.C origin=IMPLICIT_CAST typeOperand=.C - GET_VAR 'param: .B declared in .test' type=.B origin=null diff --git a/compiler/testData/ir/irText/expressions/smartCastAside.fir.kt.txt b/compiler/testData/ir/irText/expressions/smartCastAside.fir.kt.txt deleted file mode 100644 index 3e54b52217c..00000000000 --- a/compiler/testData/ir/irText/expressions/smartCastAside.fir.kt.txt +++ /dev/null @@ -1,24 +0,0 @@ -interface A { - abstract fun foo() - -} - -interface B : A { - abstract fun bar() - -} - -interface C : A { - abstract fun baz() - -} - -fun test(param: B) { - when { - param is C -> { // BLOCK - param /*as C */.foo() - param.bar() - param /*as C */.baz() - } - } -} diff --git a/compiler/testData/ir/irText/expressions/smartCastAside.kt b/compiler/testData/ir/irText/expressions/smartCastAside.kt index d391ec9b370..8c51584fbd7 100644 --- a/compiler/testData/ir/irText/expressions/smartCastAside.kt +++ b/compiler/testData/ir/irText/expressions/smartCastAside.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL interface A { fun foo() }