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 5af0c5942d3..20de96eee53 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 @@ -123,6 +123,9 @@ class ConversionTypeContext internal constructor( definitelyNotNull = false, origin = ConversionTypeOrigin.DEFAULT, invariantProjection = false ) internal val WITH_INVARIANT = DEFAULT.withInvariantProjections() + internal val IN_SETTER = ConversionTypeContext( + definitelyNotNull = false, origin = ConversionTypeOrigin.SETTER, invariantProjection = false + ) } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt index fb65691099e..c5659df4e33 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor import org.jetbrains.kotlin.fir.expressions.FirReturnExpression import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.util.isSetter import org.jetbrains.kotlin.ir.util.parentClassOrNull class Fir2IrConversionScope { @@ -134,6 +135,9 @@ class Fir2IrConversionScope { fun parent(): IrDeclarationParent? = parentStack.lastOrNull() + fun defaultConversionTypeContext(): ConversionTypeContext = + if ((parent() as? IrFunction)?.isSetter == true) ConversionTypeContext.IN_SETTER else ConversionTypeContext.DEFAULT + fun dispatchReceiverParameter(irClass: IrClass): IrValueParameter? { for (function in functionStack.asReversed()) { if (function.parentClassOrNull == irClass) { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrImplicitCastInserter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrImplicitCastInserter.kt index 389464bbf8a..e1ae0a61963 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrImplicitCastInserter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrImplicitCastInserter.kt @@ -30,9 +30,13 @@ class Fir2IrImplicitCastInserter( private val components: Fir2IrComponents ) : Fir2IrComponents by components, FirDefaultVisitor() { - private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() } + private fun FirTypeRef.toIrType(conversionTypeContext: ConversionTypeContext): IrType = with(typeConverter) { + toIrType(conversionTypeContext) + } - private fun ConeKotlinType.toIrType(): IrType = with(typeConverter) { toIrType() } + private fun ConeKotlinType.toIrType(conversionTypeContext: ConversionTypeContext): IrType = with(typeConverter) { + toIrType(conversionTypeContext) + } override fun visitElement(element: FirElement, data: IrElement): IrElement { TODO("Should not be here: ${element::class}: ${element.render()}") @@ -99,7 +103,7 @@ class Fir2IrImplicitCastInserter( override fun visitExpression(expression: FirExpression, data: IrElement): IrElement { return when (expression) { is FirBlock -> (data as IrContainerExpression).insertImplicitCasts() - is FirUnitExpression -> (data as IrExpression).let { coerceToUnitIfNeeded(it, irBuiltIns) } + is FirUnitExpression -> coerceToUnitIfNeeded(data as IrExpression, irBuiltIns) else -> data } } @@ -108,7 +112,7 @@ class Fir2IrImplicitCastInserter( return when (statement) { is FirTypeAlias -> data FirStubStatement -> data - is FirUnitExpression -> (data as IrExpression).let { coerceToUnitIfNeeded(it, irBuiltIns) } + is FirUnitExpression -> coerceToUnitIfNeeded(data as IrExpression, irBuiltIns) is FirBlock -> (data as IrContainerExpression).insertImplicitCasts() else -> statement.accept(this, data) } @@ -207,7 +211,7 @@ class Fir2IrImplicitCastInserter( } valueType.coneTypeSafe() != null -> { if (expectedType.coneType !is ConeDynamicType && !expectedType.isNullableAny) { - implicitCast(this, expectedType.toIrType()) + implicitCast(this, expectedType.toIrType(ConversionTypeContext.DEFAULT)) } else { this } @@ -298,6 +302,7 @@ class Fir2IrImplicitCastInserter( original: IrExpression, originalTypeRef: FirTypeRef, calleeReference: FirReference, + conversionTypeContext: ConversionTypeContext, ): IrExpression { val referencedDeclaration = (calleeReference.resolvedSymbol as? FirCallableSymbol<*>)?.unwrapCallRepresentative()?.fir @@ -310,19 +315,23 @@ class Fir2IrImplicitCastInserter( val castType = originalTypeRef.coneTypeSafe() castType?.intersectedTypes?.forEach { componentType -> if (AbstractTypeChecker.isSubtypeOf(session.typeContext, componentType, starProjectedDispatchReceiver)) { - return implicitCastOrExpression(original, componentType) + return implicitCastOrExpression(original, componentType, conversionTypeContext) } } - return implicitCastOrExpression(original, originalTypeRef) + return implicitCastOrExpression(original, originalTypeRef, conversionTypeContext) } - private fun implicitCastOrExpression(original: IrExpression, castType: ConeKotlinType): IrExpression { - return implicitCastOrExpression(original, castType.toIrType()) + private fun implicitCastOrExpression( + original: IrExpression, castType: ConeKotlinType, conversionTypeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT + ): IrExpression { + return implicitCastOrExpression(original, castType.toIrType(conversionTypeContext)) } - private fun implicitCastOrExpression(original: IrExpression, castType: FirTypeRef): IrExpression { - return implicitCastOrExpression(original, castType.toIrType()) + private fun implicitCastOrExpression( + original: IrExpression, castType: FirTypeRef, conversionTypeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT + ): IrExpression { + return implicitCastOrExpression(original, castType.toIrType(conversionTypeContext)) } internal fun implicitCastOrExpression(original: IrExpression, castType: IrType): IrExpression { 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 b00a8c07f32..81b8042b214 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 @@ -672,7 +672,10 @@ class Fir2IrVisitor( }?.run { if (expression is FirQualifiedAccessExpression && expression.calleeReference is FirSuperReference) return@run this - implicitCastInserter.implicitCastFromDispatchReceiver(this, expression.typeRef, calleeReference) + implicitCastInserter.implicitCastFromDispatchReceiver( + this, expression.typeRef, calleeReference, + conversionScope.defaultConversionTypeContext() + ) } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index 15943c7e87e..7a32017abd4 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -59,10 +59,11 @@ class CallAndReferenceGenerator( private val approximator = ConeTypeApproximator(session.typeContext, session.languageVersionSettings) private val adapterGenerator = AdapterGenerator(components, conversionScope) - private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() } + private fun FirTypeRef.toIrType(): IrType = + with(typeConverter) { toIrType(conversionScope.defaultConversionTypeContext()) } - private fun ConeKotlinType.toIrType(conversionTypeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT): IrType = - with(typeConverter) { toIrType(conversionTypeContext) } + private fun ConeKotlinType.toIrType(): IrType = + with(typeConverter) { toIrType(conversionScope.defaultConversionTypeContext()) } fun convertToIrCallableReference( callableReferenceAccess: FirCallableReferenceAccess, diff --git a/compiler/testData/ir/irText/declarations/genericDelegatedProperty.fir.ir.txt b/compiler/testData/ir/irText/declarations/genericDelegatedProperty.fir.ir.txt index 382ec33d913..d66b97cd35a 100644 --- a/compiler/testData/ir/irText/declarations/genericDelegatedProperty.fir.ir.txt +++ b/compiler/testData/ir/irText/declarations/genericDelegatedProperty.fir.ir.txt @@ -75,6 +75,6 @@ FILE fqName: fileName:/genericDelegatedProperty.kt CALL 'public final fun setValue (thisRef: kotlin.Any?, kProp: kotlin.Any?, newValue: kotlin.Int): kotlin.Unit [operator] declared in .Delegate' type=kotlin.Unit origin=null $this: GET_FIELD 'FIELD PROPERTY_DELEGATE name:genericDelegatedProperty$delegate type:.Delegate visibility:private [final,static]' type=.Delegate origin=null thisRef: GET_VAR ': .C.> declared in .' type=.C.> origin=null - kProp: PROPERTY_REFERENCE 'public final genericDelegatedProperty: kotlin.Int [delegated,var]' field=null getter='public final fun (): kotlin.Int declared in ' setter='public final fun (: kotlin.Int): kotlin.Unit declared in ' type=kotlin.reflect.KMutableProperty1<.C.>, kotlin.Int> origin=PROPERTY_REFERENCE_FOR_DELEGATE + kProp: PROPERTY_REFERENCE 'public final genericDelegatedProperty: kotlin.Int [delegated,var]' field=null getter='public final fun (): kotlin.Int declared in ' setter='public final fun (: kotlin.Int): kotlin.Unit declared in ' type=kotlin.reflect.KMutableProperty1<.C.>, kotlin.Int> origin=PROPERTY_REFERENCE_FOR_DELEGATE <1>: newValue: GET_VAR ': kotlin.Int declared in .' type=kotlin.Int origin=null diff --git a/compiler/testData/ir/irText/expressions/genericPropertyRef.fir.ir.txt b/compiler/testData/ir/irText/expressions/genericPropertyRef.fir.ir.txt index f2b491368c1..d28e2f7b6e9 100644 --- a/compiler/testData/ir/irText/expressions/genericPropertyRef.fir.ir.txt +++ b/compiler/testData/ir/irText/expressions/genericPropertyRef.fir.ir.txt @@ -181,7 +181,7 @@ FILE fqName: fileName:/genericPropertyRef.kt CALL 'public final fun (: kotlin.Any?): kotlin.Unit declared in ' type=kotlin.Unit origin=EQ : GET_VAR ': T of . declared in .' type=T of . origin=null CALL 'public final fun (: kotlin.Any?): kotlin.Unit declared in ' type=kotlin.Unit origin=EQ - : GET_VAR 'value: T of . declared in .' type=T of . origin=null + : GET_VAR 'value: T of . declared in .' type=T of . origin=null PROPERTY name:barRef visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:barRef type:kotlin.reflect.KMutableProperty1 visibility:private [final,static] EXPRESSION_BODY diff --git a/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.ir.txt b/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.ir.txt deleted file mode 100644 index b538f763b15..00000000000 --- a/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.ir.txt +++ /dev/null @@ -1,81 +0,0 @@ -FILE fqName: fileName:/genericPropertyReferenceType.kt - CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C.C> - TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] reified:false - CONSTRUCTOR visibility:public <> (x:T of .C) returnType:.C.C> [primary] - VALUE_PARAMETER name:x index:0 type:T of .C - BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]' - PROPERTY name:x visibility:public modality:FINAL [var] - FIELD PROPERTY_BACKING_FIELD name:x type:T of .C visibility:private - EXPRESSION_BODY - GET_VAR 'x: T of .C declared in .C.' type=T of .C origin=INITIALIZE_PROPERTY_FROM_PARAMETER - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C.C>) returnType:T of .C - correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [var] - $this: VALUE_PARAMETER name: type:.C.C> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): T of .C declared in .C' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:T of .C visibility:private' type=T of .C origin=null - receiver: GET_VAR ': .C.C> declared in .C.' type=.C.C> origin=null - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.C.C>, :T of .C) returnType:kotlin.Unit - correspondingProperty: PROPERTY name:x visibility:public modality:FINAL [var] - $this: VALUE_PARAMETER name: type:.C.C> - VALUE_PARAMETER name: index:0 type:T of .C - BLOCK_BODY - SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:x type:T of .C visibility:private' type=kotlin.Unit origin=null - receiver: GET_VAR ': .C.C> declared in .C.' type=.C.C> origin=null - value: GET_VAR ': T of .C declared in .C.' type=T of .C 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 [operator] 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 - PROPERTY name:y visibility:public modality:FINAL [var] - FUN name: visibility:public modality:FINAL ($receiver:.C.>) returnType:T of . - correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [var] - TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] reified:false - $receiver: VALUE_PARAMETER name: type:.C.> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): T of . declared in ' - CALL 'public final fun (): T of .C declared in .C' type=T of . origin=GET_PROPERTY - $this: GET_VAR ': .C.> declared in .' type=.C.> origin=null - FUN name: visibility:public modality:FINAL ($receiver:.C.>, v:T of .) returnType:kotlin.Unit - correspondingProperty: PROPERTY name:y visibility:public modality:FINAL [var] - TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] reified:false - $receiver: VALUE_PARAMETER name: type:.C.> - VALUE_PARAMETER name:v index:0 type:T of . - BLOCK_BODY - CALL 'public final fun (: T of .C): kotlin.Unit declared in .C' type=kotlin.Unit origin=EQ - $this: GET_VAR ': .C.> declared in .' type=.C.> origin=null - : GET_VAR 'v: T of . declared in .' type=T of . origin=null - FUN name:use visibility:public modality:FINAL <> (p:kotlin.reflect.KMutableProperty) returnType:kotlin.Unit - VALUE_PARAMETER name:p index:0 type:kotlin.reflect.KMutableProperty - BLOCK_BODY - FUN name:test1 visibility:public modality:FINAL <> () returnType:kotlin.Unit - BLOCK_BODY - CALL 'public final fun use (p: kotlin.reflect.KMutableProperty): kotlin.Unit declared in ' type=kotlin.Unit origin=null - p: PROPERTY_REFERENCE 'public final y: T of . [var]' field=null getter='public final fun (): T of . declared in ' setter='public final fun (v: T of .): kotlin.Unit declared in ' type=kotlin.reflect.KMutableProperty0 origin=null - <1>: kotlin.String - $receiver: CONSTRUCTOR_CALL 'public constructor (x: T of .C) [primary] declared in .C' type=.C origin=null - : kotlin.String - x: CONST String type=kotlin.String value="abc" - FUN name:test2 visibility:public modality:FINAL <> (a:kotlin.Any) returnType:kotlin.Unit - VALUE_PARAMETER name:a index:0 type:kotlin.Any - BLOCK_BODY - TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit - TYPE_OP type=.C origin=CAST typeOperand=.C - GET_VAR 'a: kotlin.Any declared in .test2' type=kotlin.Any origin=null - CALL 'public final fun use (p: kotlin.reflect.KMutableProperty): kotlin.Unit declared in ' type=kotlin.Unit origin=null - p: PROPERTY_REFERENCE 'public final y: T of . [var]' field=null getter='public final fun (): T of . declared in ' setter='public final fun (v: T of .): kotlin.Unit declared in ' type=kotlin.reflect.KMutableProperty0 origin=null - <1>: kotlin.String - $receiver: TYPE_OP type=.C origin=IMPLICIT_CAST typeOperand=.C - GET_VAR 'a: kotlin.Any declared in .test2' type=kotlin.Any origin=null diff --git a/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.kt.txt b/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.kt.txt deleted file mode 100644 index 19607410ad6..00000000000 --- a/compiler/testData/ir/irText/types/genericPropertyReferenceType.fir.kt.txt +++ /dev/null @@ -1,34 +0,0 @@ -class C { - constructor(x: T) /* primary */ { - super/*Any*/() - /* () */ - - } - - var x: T - field = x - get - set - -} - -var C.y: T - get(): T { - return .() - } - set(v: T) { - .( = v) - } - -fun use(p: KMutableProperty) { -} - -fun test1() { - use(p = C(x = "abc")::y/*()*/) -} - -fun test2(a: Any) { - a as C /*~> Unit */ - use(p = a /*as C */::y/*()*/) -} - diff --git a/compiler/testData/ir/irText/types/genericPropertyReferenceType.kt b/compiler/testData/ir/irText/types/genericPropertyReferenceType.kt index 0a6b18c7682..1ba698a4d21 100644 --- a/compiler/testData/ir/irText/types/genericPropertyReferenceType.kt +++ b/compiler/testData/ir/irText/types/genericPropertyReferenceType.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL import kotlin.reflect.KMutableProperty class C(var x: T)