diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt index 21d825e20c9..d59258f2747 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt @@ -86,6 +86,17 @@ sealed class ResolutionMode { } } + /** + * This resolution mode is used for resolving the LHS of assignments. + * + * It is generally treated like [ContextIndependent], however it carries the containing assignment which is needed for + * call-site-dependant resolution to detect cases where the setter of the called property needs to be considered instead of the getter. + * + * Examples are: + * + * - assigning to a property with a setter that has a different visibility than the property + * - assigning to a non-deprecated property with a setter that is deprecated + */ class AssignmentLValue(val variableAssignment: FirVariableAssignment) : ResolutionMode() { override fun toString(): String = "AssignmentLValue: ${variableAssignment.render()}" } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index b6a997c7752..a59137a3a71 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -151,7 +151,8 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT val transformedCallee = resolveQualifiedAccessAndSelectCandidate( qualifiedAccessExpression, isUsedAsReceiver, - when (data) { + // Set the correct call site. For assignment LHSs, it's the assignment, otherwise it's the qualified access itself. + callSite = when (data) { is ResolutionMode.AssignmentLValue -> data.variableAssignment else -> qualifiedAccessExpression } @@ -168,6 +169,9 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT } } } + + // If we're resolving the LHS of an assignment, skip DFA to prevent the access being treated as a variable read and + // smart-casts being applied. if (data !is ResolutionMode.AssignmentLValue) { when (result) { is FirQualifiedAccessExpression -> {