From cc1b608661834bf9b1668950c987ccae3b3b1cbe Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Thu, 1 Dec 2022 11:31:04 +0100 Subject: [PATCH] K2: Merge all expected-type related resolution modes into single class It looks more natural and allows to combine different properties of these cases --- .../kotlin/fir/resolve/ResolutionMode.kt | 56 ++++++------------- .../fir/resolve/inference/FirCallCompleter.kt | 4 +- .../FirDeclarationsResolveTransformer.kt | 6 +- .../FirExpressionsResolveTransformer.kt | 2 +- 4 files changed, 21 insertions(+), 47 deletions(-) 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 d59258f2747..3a43a2914d1 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 @@ -33,9 +33,22 @@ sealed class ResolutionMode { val expectedTypeRef: FirTypeRef, val mayBeCoercionToUnitApplied: Boolean = false, val expectedTypeMismatchIsReportedInChecker: Boolean = false, + val fromCast: Boolean = false, + // It might be ok if the types turn out to be incompatible + // Consider the following examples with properties and their backing fields: + // + // val items: List field = mutableListOf() + // val s: String field = 10 get() = ... + // In these examples we should try using the property type information while resolving the initializer, + // but it's ok if it's not applicable + val shouldBeStrictlyEnforced: Boolean = true, ) : ResolutionMode() { override fun toString(): String { - return "WithExpectedType: ${expectedTypeRef.prettyString()}" + return "WithExpectedType: ${expectedTypeRef.prettyString()}, " + + "mayBeCoercionToUnitApplied=${mayBeCoercionToUnitApplied}, " + + "expectedTypeMismatchIsReportedInChecker=${expectedTypeMismatchIsReportedInChecker}, " + + "fromCast=${fromCast}, " + + "shouldBeStrictlyEnforced=${shouldBeStrictlyEnforced}, " } } @@ -51,41 +64,6 @@ sealed class ResolutionMode { } } - class WithExpectedTypeFromCast( - val expectedTypeRef: FirTypeRef, - ) : ResolutionMode() { - override fun toString(): String { - return "WithExpectedTypeFromCast: ${expectedTypeRef.prettyString()}" - } - } - - /** - * This resolution mode is similar to - * WithExpectedType, but it's ok if the - * types turn out to be incompatible. - * Consider the following examples with - * properties and their backing fields: - * - * val items: List - * field = mutableListOf() - * - * val s: String - * field = 10 - * get() = ... - * - * In these examples we should try using - * the property type information while - * resolving the initializer, but it's ok - * if it's not applicable. - */ - class WithSuggestedType( - val suggestedTypeRef: FirTypeRef, - ) : ResolutionMode() { - override fun toString(): String { - return "WithSuggestedType: ${suggestedTypeRef.prettyString()}" - } - } - /** * This resolution mode is used for resolving the LHS of assignments. * @@ -110,13 +88,11 @@ sealed class ResolutionMode { } } -fun ResolutionMode.expectedType(components: BodyResolveComponents, allowFromCast: Boolean = false): FirTypeRef? = when (this) { - is ResolutionMode.WithExpectedType -> expectedTypeRef +fun ResolutionMode.expectedType(components: BodyResolveComponents): FirTypeRef? = when (this) { + is ResolutionMode.WithExpectedType -> expectedTypeRef.takeIf { !this.fromCast } is ResolutionMode.ContextIndependent, is ResolutionMode.AssignmentLValue, is ResolutionMode.ReceiverResolution -> components.noExpectedType - is ResolutionMode.WithExpectedTypeFromCast -> expectedTypeRef.takeIf { allowFromCast } - is ResolutionMode.WithSuggestedType -> suggestedTypeRef else -> null } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt index f07472dd6cf..ce579e7a753 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt @@ -76,8 +76,8 @@ class FirCallCompleter( data.expectedType(components, allowFromCast = true), (data as? ResolutionMode.WithExpectedType)?.mayBeCoercionToUnitApplied == true, (data as? ResolutionMode.WithExpectedType)?.expectedTypeMismatchIsReportedInChecker == true, - isFromCast = data is ResolutionMode.WithExpectedTypeFromCast, - shouldEnforceExpectedType = data !is ResolutionMode.WithSuggestedType, + isFromCast = (data as? ResolutionMode.WithExpectedType)?.fromCast == true, + shouldEnforceExpectedType = (data as? ResolutionMode.WithExpectedType)?.shouldBeStrictlyEnforced == true, ) private fun completeCall( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 12229a40bd6..70df3af8bc0 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -728,11 +728,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve } is ResolutionMode.WithExpectedType -> transformAnonymousFunctionWithExpectedType(anonymousFunction, data.expectedTypeRef, data) - is ResolutionMode.WithSuggestedType -> - transformAnonymousFunctionWithExpectedType(anonymousFunction, data.suggestedTypeRef, data) is ResolutionMode.ContextIndependent, is ResolutionMode.AssignmentLValue, is ResolutionMode.ReceiverResolution -> transformAnonymousFunctionWithExpectedType(anonymousFunction, buildImplicitTypeRef(), data) - is ResolutionMode.WithStatus, is ResolutionMode.WithExpectedTypeFromCast -> + is ResolutionMode.WithStatus -> throw AssertionError("Should not be here in WithStatus/WithExpectedTypeFromCast mode") } } @@ -888,7 +886,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve val initializerData = if (backingField.returnTypeRef is FirResolvedTypeRef) { withExpectedType(backingField.returnTypeRef) } else if (propertyType != null) { - ResolutionMode.WithSuggestedType(propertyType) + ResolutionMode.WithExpectedType(propertyType, shouldBeStrictlyEnforced = false) } else { ResolutionMode.ContextDependent } 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 ecc4e7c4bc0..0c13390fb56 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 @@ -800,7 +800,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT } if (expectedType != null) { - val newMode = ResolutionMode.WithExpectedTypeFromCast(conversionTypeRef.withReplacedConeType(expectedType)) + val newMode = ResolutionMode.WithExpectedType(conversionTypeRef.withReplacedConeType(expectedType), fromCast = true) return transformOtherChildren(transformer, newMode) } }