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.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
@@ -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 {
@@ -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)
@@ -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 (
@@ -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,
)