From 289efd47b26402b6076327ecac1fe07b7b185f88 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 22 Oct 2020 10:43:47 +0300 Subject: [PATCH] [FIR2IR] Cleanup code around implicit casts --- .../kotlin/fir/backend/Fir2IrVisitor.kt | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 45ccd01db2a..5d36652269d 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.backend import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.* @@ -424,10 +423,19 @@ class Fir2IrVisitor( return visitQualifiedAccessExpression(thisReceiverExpression, data) } - private fun implicitCastOrExpression(original: IrExpression, castType: IrType, isThisInLocalFun: Boolean = false): IrExpression { - // If the original is a "this" in a local function and original.type is the same as castType, - // we still want to keep the cast. See kt-42517 - if (original.type == castType && !isThisInLocalFun) return original + private fun implicitCastOrExpression(original: IrExpression, castType: ConeKotlinType): IrExpression { + return implicitCastOrExpression(original, castType.toIrType()) + } + + private fun implicitCastOrExpression(original: IrExpression, castType: FirTypeRef): IrExpression { + return implicitCastOrExpression(original, castType.toIrType()) + } + + private fun implicitCastOrExpression(original: IrExpression, castType: IrType): IrExpression { + return original.takeIf { it.type == castType } ?: implicitCast(original, castType) + } + + private fun implicitCast(original: IrExpression, castType: IrType): IrExpression { return IrTypeOperatorCallImpl( original.startOffset, original.endOffset, @@ -438,14 +446,6 @@ class Fir2IrVisitor( ) } - private fun implicitCastOrExpression(original: IrExpression, castType: ConeKotlinType): IrExpression { - return implicitCastOrExpression(original, castType.toIrType()) - } - - private fun implicitCastOrExpression(original: IrExpression, castType: FirTypeRef): IrExpression { - return implicitCastOrExpression(original, castType.toIrType()) - } - private fun ConeKotlinType.doesContainReferencedSymbolInScope( referencedSymbol: AbstractFirBasedSymbol<*>, name: Name ): Boolean { @@ -466,7 +466,8 @@ class Fir2IrVisitor( private fun convertToImplicitCastExpression( expressionWithSmartcast: FirExpressionWithSmartcast, calleeReference: FirReference ): IrExpression { - val value = convertToIrExpression(expressionWithSmartcast.originalExpression) + val originalExpression = expressionWithSmartcast.originalExpression + val value = convertToIrExpression(originalExpression) val castTypeRef = expressionWithSmartcast.typeRef if (calleeReference !is FirResolvedNamedReference) { return implicitCastOrExpression(value, castTypeRef) @@ -488,9 +489,15 @@ class Fir2IrVisitor( } } } - val isLocalFun = ((value as? IrGetValue)?.symbol?.owner?.parent as? IrFunction)?.visibility == DescriptorVisibilities.LOCAL - return implicitCastOrExpression(value, castTypeRef.toIrType(), - isLocalFun && expressionWithSmartcast.originalExpression is FirThisReceiverExpression) + return if (originalExpression is FirThisReceiverExpression && + originalExpression.calleeReference.boundSymbol is FirAnonymousFunctionSymbol + ) { + // If the original is a "this" in a local function and original.type is the same as castType, + // we still want to keep the cast. See kt-42517 + implicitCast(value, castTypeRef.toIrType()) + } else { + implicitCastOrExpression(value, castTypeRef.toIrType()) + } } override fun visitExpressionWithSmartcast(expressionWithSmartcast: FirExpressionWithSmartcast, data: Any?): IrElement {