diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index 974b660960f..4d7ef9bf8b6 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -841,13 +841,19 @@ internal fun FirClass.declaredScope(): FirContainingNamesAwareScope { return symbol.declaredScope() } -internal fun implicitCast(original: IrExpression, castType: IrType, typeOperator: IrTypeOperator): IrTypeOperatorCall { - return IrTypeOperatorCallImpl( - original.startOffset, - original.endOffset, - castType, - typeOperator, - castType, - original - ) +internal fun implicitCast(original: IrExpression, castType: IrType, typeOperator: IrTypeOperator): IrExpression { + if (original.type == castType) { + return original + } + if (original !is IrTypeOperatorCall) { + return IrTypeOperatorCallImpl( + original.startOffset, + original.endOffset, + castType, + typeOperator, + castType, + original + ) + } + return implicitCast(original.argument, castType, typeOperator) } diff --git a/compiler/testData/ir/irText/expressions/smartCastAside.fir.ir.txt b/compiler/testData/ir/irText/expressions/smartCastAside.fir.ir.txt index 95cc9c41031..39db290b85a 100644 --- a/compiler/testData/ir/irText/expressions/smartCastAside.fir.ir.txt +++ b/compiler/testData/ir/irText/expressions/smartCastAside.fir.ir.txt @@ -68,13 +68,9 @@ FILE fqName: fileName:/smartCastAside.kt 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 - TYPE_OP type=.A origin=IMPLICIT_CAST typeOperand=.A - GET_VAR 'param: .B declared in .test' type=.B origin=null + 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: TYPE_OP type=.B origin=IMPLICIT_CAST typeOperand=.B - TYPE_OP type=.A origin=IMPLICIT_CAST typeOperand=.A - GET_VAR 'param: .B declared in .test' type=.B 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 - TYPE_OP type=.A origin=IMPLICIT_CAST typeOperand=.A - GET_VAR 'param: .B declared in .test' type=.B origin=null + 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 index fa1fe3840af..3e54b52217c 100644 --- a/compiler/testData/ir/irText/expressions/smartCastAside.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/smartCastAside.fir.kt.txt @@ -16,9 +16,9 @@ interface C : A { fun test(param: B) { when { param is C -> { // BLOCK - param /*as A */ /*as C */.foo() - param /*as A */ /*as B */.bar() - param /*as A */ /*as C */.baz() + param /*as C */.foo() + param.bar() + param /*as C */.baz() } } } diff --git a/compiler/testData/ir/irText/firProblems/Modality.fir.ir.txt b/compiler/testData/ir/irText/firProblems/Modality.fir.ir.txt deleted file mode 100644 index a2f1b7b979b..00000000000 --- a/compiler/testData/ir/irText/firProblems/Modality.fir.ir.txt +++ /dev/null @@ -1,170 +0,0 @@ -FILE fqName: fileName:/Modality.kt - CLASS INTERFACE name:Substitutable modality:ABSTRACT visibility:public superTypes:[kotlin.Any] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Substitutable.Substitutable> - TYPE_PARAMETER name:T index:0 variance:out superTypes:[.DeclarationDescriptorNonRoot] reified:false - 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 CLASS name:ResolutionPart modality:ABSTRACT visibility:public superTypes:[kotlin.Any] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.ResolutionPart - CONSTRUCTOR visibility:public <> () returnType:.ResolutionPart [primary] - BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:ResolutionPart modality:ABSTRACT visibility:public superTypes:[kotlin.Any]' - FUN name:process visibility:public modality:ABSTRACT <> ($this:.ResolutionPart, $receiver:.KotlinResolutionCandidate) returnType:kotlin.String - $this: VALUE_PARAMETER name: type:.ResolutionPart - $receiver: VALUE_PARAMETER name: type:.KotlinResolutionCandidate - 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 CLASS name:KotlinResolutionCandidate modality:FINAL visibility:public superTypes:[kotlin.Any] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.KotlinResolutionCandidate - CONSTRUCTOR visibility:public <> (resolvedCall:.Atom) returnType:.KotlinResolutionCandidate [primary] - VALUE_PARAMETER name:resolvedCall index:0 type:.Atom - BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:KotlinResolutionCandidate modality:FINAL visibility:public superTypes:[kotlin.Any]' - PROPERTY name:resolvedCall visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:resolvedCall type:.Atom visibility:private [final] - EXPRESSION_BODY - GET_VAR 'resolvedCall: .Atom declared in .KotlinResolutionCandidate.' type=.Atom origin=INITIALIZE_PROPERTY_FROM_PARAMETER - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.KotlinResolutionCandidate) returnType:.Atom - correspondingProperty: PROPERTY name:resolvedCall visibility:public modality:FINAL [val] - $this: VALUE_PARAMETER name: type:.KotlinResolutionCandidate - BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): .Atom declared in .KotlinResolutionCandidate' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:resolvedCall type:.Atom visibility:private [final]' type=.Atom origin=null - receiver: GET_VAR ': .KotlinResolutionCandidate declared in .KotlinResolutionCandidate.' type=.KotlinResolutionCandidate origin=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 - CLASS CLASS name:Atom modality:FINAL visibility:public superTypes:[kotlin.Any] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Atom - CONSTRUCTOR visibility:public <> (candidateDescriptor:.CallableDescriptor) returnType:.Atom [primary] - VALUE_PARAMETER name:candidateDescriptor index:0 type:.CallableDescriptor - BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Atom modality:FINAL visibility:public superTypes:[kotlin.Any]' - PROPERTY name:candidateDescriptor visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:candidateDescriptor type:.CallableDescriptor visibility:private [final] - EXPRESSION_BODY - GET_VAR 'candidateDescriptor: .CallableDescriptor declared in .Atom.' type=.CallableDescriptor origin=INITIALIZE_PROPERTY_FROM_PARAMETER - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Atom) returnType:.CallableDescriptor - correspondingProperty: PROPERTY name:candidateDescriptor visibility:public modality:FINAL [val] - $this: VALUE_PARAMETER name: type:.Atom - BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): .CallableDescriptor declared in .Atom' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:candidateDescriptor type:.CallableDescriptor visibility:private [final]' type=.CallableDescriptor origin=null - receiver: GET_VAR ': .Atom declared in .Atom.' type=.Atom origin=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 - CLASS OBJECT name:Owner modality:FINAL visibility:public superTypes:[.ResolutionPart] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Owner - CONSTRUCTOR visibility:private <> () returnType:.Owner [primary] - BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in .ResolutionPart' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name:Owner modality:FINAL visibility:public superTypes:[.ResolutionPart]' - FUN name:process visibility:public modality:OPEN <> ($this:.Owner, $receiver:.KotlinResolutionCandidate) returnType:kotlin.String - overridden: - public abstract fun process (): kotlin.String declared in .ResolutionPart - $this: VALUE_PARAMETER name: type:.Owner - $receiver: VALUE_PARAMETER name: type:.KotlinResolutionCandidate - BLOCK_BODY - VAR name:candidateDescriptor type:.CallableDescriptor [val] - CALL 'public final fun (): .CallableDescriptor declared in .Atom' type=.CallableDescriptor origin=GET_PROPERTY - $this: CALL 'public final fun (): .Atom declared in .KotlinResolutionCandidate' type=.Atom origin=GET_PROPERTY - $this: GET_VAR ': .KotlinResolutionCandidate declared in .Owner.process' type=.KotlinResolutionCandidate origin=null - WHEN type=kotlin.Unit origin=IF - BRANCH - if: WHEN type=kotlin.Boolean origin=ANDAND - BRANCH - if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=.MemberDescriptor - GET_VAR 'val candidateDescriptor: .CallableDescriptor declared in .Owner.process' type=.CallableDescriptor origin=null - then: CALL 'public final fun not (): kotlin.Boolean declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ - $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ - arg0: CALL 'public abstract fun getModality (): @[FlexibleNullability] .Modality? declared in .MemberDescriptor' type=@[FlexibleNullability] .Modality? origin=GET_PROPERTY - $this: TYPE_OP type=.MemberDescriptor origin=IMPLICIT_CAST typeOperand=.MemberDescriptor - TYPE_OP type=.DeclarationDescriptor origin=IMPLICIT_CAST typeOperand=.DeclarationDescriptor - GET_VAR 'val candidateDescriptor: .CallableDescriptor declared in .Owner.process' type=.CallableDescriptor origin=null - arg1: CONST Null type=kotlin.Nothing? value=null - BRANCH - if: CONST Boolean type=kotlin.Boolean value=true - then: CONST Boolean type=kotlin.Boolean value=false - then: BLOCK type=kotlin.Unit origin=null - RETURN type=kotlin.Nothing from='public open fun process (): kotlin.String declared in .Owner' - CONST String type=kotlin.String value="OK" - RETURN type=kotlin.Nothing from='public open fun process (): kotlin.String declared in .Owner' - CONST String type=kotlin.String value="FAIL" - 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 .ResolutionPart - $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 .ResolutionPart - $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 .ResolutionPart - $this: VALUE_PARAMETER name: type:kotlin.Any - CLASS OBJECT name:Final modality:FINAL visibility:public superTypes:[.Modality] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Final - CONSTRUCTOR visibility:private <> () returnType:.Final [primary] - BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name:Final modality:FINAL visibility:public superTypes:[.Modality]' - 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 .Modality - $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 .Modality - $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 .Modality - $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/testData/ir/irText/firProblems/Modality.fir.kt.txt b/compiler/testData/ir/irText/firProblems/Modality.fir.kt.txt deleted file mode 100644 index daa7f3b849b..00000000000 --- a/compiler/testData/ir/irText/firProblems/Modality.fir.kt.txt +++ /dev/null @@ -1,71 +0,0 @@ -interface Substitutable { - -} - -abstract class ResolutionPart { - constructor() /* primary */ { - super/*Any*/() - /* () */ - - } - - abstract fun KotlinResolutionCandidate.process(): String - -} - -class KotlinResolutionCandidate { - constructor(resolvedCall: Atom) /* primary */ { - super/*Any*/() - /* () */ - - } - - val resolvedCall: Atom - field = resolvedCall - get - -} - -class Atom { - constructor(candidateDescriptor: CallableDescriptor) /* primary */ { - super/*Any*/() - /* () */ - - } - - val candidateDescriptor: CallableDescriptor - field = candidateDescriptor - get - -} - -object Owner : ResolutionPart { - private constructor() /* primary */ { - super/*ResolutionPart*/() - /* () */ - - } - - override fun KotlinResolutionCandidate.process(): String { - val candidateDescriptor: CallableDescriptor = .().() - when { - when { - candidateDescriptor is MemberDescriptor -> EQEQ(arg0 = candidateDescriptor /*as DeclarationDescriptor */ /*as MemberDescriptor */.getModality(), arg1 = null).not() - else -> false - } -> { // BLOCK - return "OK" - } - } - return "FAIL" - } - -} - -object Final : Modality { - private constructor() /* primary */ { - super/*Any*/() - /* () */ - - } - -} diff --git a/compiler/testData/ir/irText/firProblems/Modality.kt b/compiler/testData/ir/irText/firProblems/Modality.kt index ce386c20b3a..bf0d95a17c8 100644 --- a/compiler/testData/ir/irText/firProblems/Modality.kt +++ b/compiler/testData/ir/irText/firProblems/Modality.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // TARGET_BACKEND: JVM // FILE: Modality.java public interface Modality