From e43d8bbb47325e40304e6e4d1953a5c831bb401e Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Fri, 2 Dec 2022 17:16:18 +0100 Subject: [PATCH] K2: Require resolved type for ResolutionMode.WithExpectedType Implicit type might have two meaning there: - noExpectedType - unknown declaration type where this expression is assigned to For both cases, we've got ResolutionMode.ContextIndependent that works just fine --- .../fir/resolver/SingleCandidateResolver.kt | 4 ++- .../kotlin/fir/resolve/ResolutionMode.kt | 17 ++++++----- ...ControlFlowStatementsResolveTransformer.kt | 11 ++++---- .../FirDeclarationsResolveTransformer.kt | 28 +++++++++++++------ .../FirExpressionsResolveTransformer.kt | 2 +- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/SingleCandidateResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/SingleCandidateResolver.kt index 32e9ed657e2..52f44b298c3 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/SingleCandidateResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolver/SingleCandidateResolver.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.createConeDiagnosticForCandidateWithError import org.jetbrains.kotlin.fir.resolve.inference.FirCallCompleter import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.FirTypeProjection import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability @@ -77,7 +78,8 @@ class SingleCandidateResolver( val completionResult = firCallCompleter.completeCall( fakeCall, - resolutionParameters.expectedType?.let(ResolutionMode::WithExpectedType) ?: ResolutionMode.ContextIndependent + (resolutionParameters.expectedType as? FirResolvedTypeRef)?.let { ResolutionMode.WithExpectedType(it) } + ?: ResolutionMode.ContextIndependent ) return completionResult.takeIf { it.callCompleted }?.result 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 d6e97ab01d8..4e1adaa3b77 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 @@ -28,9 +28,8 @@ sealed class ResolutionMode(val forceFullCompletion: Boolean) { override fun toString(): String = "ReceiverResolution" } - // TODO: it's better not to use WithExpectedType(FirImplicitTypeRef) class WithExpectedType( - val expectedTypeRef: FirTypeRef, + val expectedTypeRef: FirResolvedTypeRef, val mayBeCoercionToUnitApplied: Boolean = false, val expectedTypeMismatchIsReportedInChecker: Boolean = false, val fromCast: Boolean = false, @@ -96,13 +95,13 @@ fun ResolutionMode.expectedType(components: BodyResolveComponents): FirTypeRef? else -> null } -fun withExpectedType(expectedTypeRef: FirTypeRef?, expectedTypeMismatchIsReportedInChecker: Boolean = false): ResolutionMode = - expectedTypeRef?.let { - ResolutionMode.WithExpectedType( - it, - expectedTypeMismatchIsReportedInChecker = expectedTypeMismatchIsReportedInChecker - ) - } ?: ResolutionMode.ContextDependent +fun withExpectedType(expectedTypeRef: FirTypeRef, expectedTypeMismatchIsReportedInChecker: Boolean = false): ResolutionMode = when { + expectedTypeRef is FirResolvedTypeRef -> ResolutionMode.WithExpectedType( + expectedTypeRef, + expectedTypeMismatchIsReportedInChecker = expectedTypeMismatchIsReportedInChecker + ) + else -> ResolutionMode.ContextIndependent +} @JvmName("withExpectedTypeNullable") fun withExpectedType(coneType: ConeKotlinType?, mayBeCoercionToUnitApplied: Boolean = false): ResolutionMode { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt index b6763e1b199..00e28b6db61 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt @@ -210,14 +210,13 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes val labeledElement = returnExpression.target.labeledElement val expectedTypeRef = labeledElement.returnTypeRef - @Suppress("IntroduceWhenSubject") val mode = when { - labeledElement.symbol in context.anonymousFunctionsAnalyzedInDependentContext -> { - ResolutionMode.ContextDependent - } - else -> { + labeledElement.symbol in context.anonymousFunctionsAnalyzedInDependentContext -> ResolutionMode.ContextDependent + + expectedTypeRef is FirResolvedTypeRef -> ResolutionMode.WithExpectedType(expectedTypeRef, expectedTypeMismatchIsReportedInChecker = true) - } + + else -> ResolutionMode.ContextIndependent } return transformJump(returnExpression, mode) 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 70df3af8bc0..ee4f3ef743a 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 @@ -285,7 +285,13 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve val stubTypeCompletionResultsWriter = FirStubTypeTransformer(finalSubstitutor) property.transformSingle(stubTypeCompletionResultsWriter, null) - property.replaceReturnTypeRef(property.returnTypeRef.approximateDeclarationType(session, property.visibilityForApproximation(), property.isLocal)) + property.replaceReturnTypeRef( + property.returnTypeRef.approximateDeclarationType( + session, + property.visibilityForApproximation(), + property.isLocal + ) + ) val callCompletionResultsWriter = callCompleter.createCompletionResultsWriter( finalSubstitutor, @@ -745,7 +751,10 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve val lambdaType = anonymousFunction.typeRef return context.withAnonymousFunction(anonymousFunction, components, data) { withFullBodyResolve { - transformFunction(anonymousFunction, withExpectedType(expectedReturnTypeRef)) as FirAnonymousFunction + transformFunction( + anonymousFunction, + expectedReturnTypeRef?.let(::withExpectedType) ?: ResolutionMode.ContextDependent + ) as FirAnonymousFunction } }.apply { replaceTypeRef(lambdaType) } } @@ -883,12 +892,15 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve data: ResolutionMode, ): FirStatement = whileAnalysing(session, backingField) { val propertyType = data.expectedType - val initializerData = if (backingField.returnTypeRef is FirResolvedTypeRef) { - withExpectedType(backingField.returnTypeRef) - } else if (propertyType != null) { - ResolutionMode.WithExpectedType(propertyType, shouldBeStrictlyEnforced = false) - } else { - ResolutionMode.ContextDependent + val initializerData = when { + backingField.returnTypeRef is FirResolvedTypeRef -> withExpectedType(backingField.returnTypeRef) + + propertyType is FirResolvedTypeRef -> + ResolutionMode.WithExpectedType(propertyType, shouldBeStrictlyEnforced = false) + + propertyType != null -> ResolutionMode.ContextIndependent + + else -> ResolutionMode.ContextDependent } backingField.transformInitializer(transformer, initializerData) if ( 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 4d41bab8140..c46c8eba5d8 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 @@ -615,7 +615,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT fun chooseOperator(): FirStatement { callCompleter.completeCall( resolvedOperatorCall, - lhsVariable?.returnTypeRef?.let { + (lhsVariable?.returnTypeRef as? FirResolvedTypeRef)?.let { ResolutionMode.WithExpectedType(it, expectedTypeMismatchIsReportedInChecker = true) } ?: ResolutionMode.ContextIndependent, )