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
This commit is contained in:
Denis.Zharkov
2022-12-02 17:16:18 +01:00
committed by Space Team
parent df826f04a7
commit e43d8bbb47
5 changed files with 37 additions and 25 deletions
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.createConeDiagnosticForCandidateWithError import org.jetbrains.kotlin.fir.resolve.createConeDiagnosticForCandidateWithError
import org.jetbrains.kotlin.fir.resolve.inference.FirCallCompleter import org.jetbrains.kotlin.fir.resolve.inference.FirCallCompleter
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol 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.FirTypeProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
@@ -77,7 +78,8 @@ class SingleCandidateResolver(
val completionResult = firCallCompleter.completeCall( val completionResult = firCallCompleter.completeCall(
fakeCall, fakeCall,
resolutionParameters.expectedType?.let(ResolutionMode::WithExpectedType) ?: ResolutionMode.ContextIndependent (resolutionParameters.expectedType as? FirResolvedTypeRef)?.let { ResolutionMode.WithExpectedType(it) }
?: ResolutionMode.ContextIndependent
) )
return completionResult.takeIf { it.callCompleted }?.result return completionResult.takeIf { it.callCompleted }?.result
@@ -28,9 +28,8 @@ sealed class ResolutionMode(val forceFullCompletion: Boolean) {
override fun toString(): String = "ReceiverResolution" override fun toString(): String = "ReceiverResolution"
} }
// TODO: it's better not to use WithExpectedType(FirImplicitTypeRef)
class WithExpectedType( class WithExpectedType(
val expectedTypeRef: FirTypeRef, val expectedTypeRef: FirResolvedTypeRef,
val mayBeCoercionToUnitApplied: Boolean = false, val mayBeCoercionToUnitApplied: Boolean = false,
val expectedTypeMismatchIsReportedInChecker: Boolean = false, val expectedTypeMismatchIsReportedInChecker: Boolean = false,
val fromCast: Boolean = false, val fromCast: Boolean = false,
@@ -96,13 +95,13 @@ fun ResolutionMode.expectedType(components: BodyResolveComponents): FirTypeRef?
else -> null else -> null
} }
fun withExpectedType(expectedTypeRef: FirTypeRef?, expectedTypeMismatchIsReportedInChecker: Boolean = false): ResolutionMode = fun withExpectedType(expectedTypeRef: FirTypeRef, expectedTypeMismatchIsReportedInChecker: Boolean = false): ResolutionMode = when {
expectedTypeRef?.let { expectedTypeRef is FirResolvedTypeRef -> ResolutionMode.WithExpectedType(
ResolutionMode.WithExpectedType( expectedTypeRef,
it, expectedTypeMismatchIsReportedInChecker = expectedTypeMismatchIsReportedInChecker
expectedTypeMismatchIsReportedInChecker = expectedTypeMismatchIsReportedInChecker )
) else -> ResolutionMode.ContextIndependent
} ?: ResolutionMode.ContextDependent }
@JvmName("withExpectedTypeNullable") @JvmName("withExpectedTypeNullable")
fun withExpectedType(coneType: ConeKotlinType?, mayBeCoercionToUnitApplied: Boolean = false): ResolutionMode { fun withExpectedType(coneType: ConeKotlinType?, mayBeCoercionToUnitApplied: Boolean = false): ResolutionMode {
@@ -210,14 +210,13 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
val labeledElement = returnExpression.target.labeledElement val labeledElement = returnExpression.target.labeledElement
val expectedTypeRef = labeledElement.returnTypeRef val expectedTypeRef = labeledElement.returnTypeRef
@Suppress("IntroduceWhenSubject")
val mode = when { val mode = when {
labeledElement.symbol in context.anonymousFunctionsAnalyzedInDependentContext -> { labeledElement.symbol in context.anonymousFunctionsAnalyzedInDependentContext -> ResolutionMode.ContextDependent
ResolutionMode.ContextDependent
} expectedTypeRef is FirResolvedTypeRef ->
else -> {
ResolutionMode.WithExpectedType(expectedTypeRef, expectedTypeMismatchIsReportedInChecker = true) ResolutionMode.WithExpectedType(expectedTypeRef, expectedTypeMismatchIsReportedInChecker = true)
}
else -> ResolutionMode.ContextIndependent
} }
return transformJump(returnExpression, mode) return transformJump(returnExpression, mode)
@@ -285,7 +285,13 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
val stubTypeCompletionResultsWriter = FirStubTypeTransformer(finalSubstitutor) val stubTypeCompletionResultsWriter = FirStubTypeTransformer(finalSubstitutor)
property.transformSingle(stubTypeCompletionResultsWriter, null) 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( val callCompletionResultsWriter = callCompleter.createCompletionResultsWriter(
finalSubstitutor, finalSubstitutor,
@@ -745,7 +751,10 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
val lambdaType = anonymousFunction.typeRef val lambdaType = anonymousFunction.typeRef
return context.withAnonymousFunction(anonymousFunction, components, data) { return context.withAnonymousFunction(anonymousFunction, components, data) {
withFullBodyResolve { withFullBodyResolve {
transformFunction(anonymousFunction, withExpectedType(expectedReturnTypeRef)) as FirAnonymousFunction transformFunction(
anonymousFunction,
expectedReturnTypeRef?.let(::withExpectedType) ?: ResolutionMode.ContextDependent
) as FirAnonymousFunction
} }
}.apply { replaceTypeRef(lambdaType) } }.apply { replaceTypeRef(lambdaType) }
} }
@@ -883,12 +892,15 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
data: ResolutionMode, data: ResolutionMode,
): FirStatement = whileAnalysing(session, backingField) { ): FirStatement = whileAnalysing(session, backingField) {
val propertyType = data.expectedType val propertyType = data.expectedType
val initializerData = if (backingField.returnTypeRef is FirResolvedTypeRef) { val initializerData = when {
withExpectedType(backingField.returnTypeRef) backingField.returnTypeRef is FirResolvedTypeRef -> withExpectedType(backingField.returnTypeRef)
} else if (propertyType != null) {
ResolutionMode.WithExpectedType(propertyType, shouldBeStrictlyEnforced = false) propertyType is FirResolvedTypeRef ->
} else { ResolutionMode.WithExpectedType(propertyType, shouldBeStrictlyEnforced = false)
ResolutionMode.ContextDependent
propertyType != null -> ResolutionMode.ContextIndependent
else -> ResolutionMode.ContextDependent
} }
backingField.transformInitializer(transformer, initializerData) backingField.transformInitializer(transformer, initializerData)
if ( if (
@@ -615,7 +615,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
fun chooseOperator(): FirStatement { fun chooseOperator(): FirStatement {
callCompleter.completeCall( callCompleter.completeCall(
resolvedOperatorCall, resolvedOperatorCall,
lhsVariable?.returnTypeRef?.let { (lhsVariable?.returnTypeRef as? FirResolvedTypeRef)?.let {
ResolutionMode.WithExpectedType(it, expectedTypeMismatchIsReportedInChecker = true) ResolutionMode.WithExpectedType(it, expectedTypeMismatchIsReportedInChecker = true)
} ?: ResolutionMode.ContextIndependent, } ?: ResolutionMode.ContextIndependent,
) )