K2: drop nullable results for generated synthetic callees

This commit is contained in:
Mikhail Glukhikh
2023-05-03 15:32:47 +02:00
committed by Space Team
parent 3964ee38be
commit af7d6b1bb3
3 changed files with 23 additions and 47 deletions
@@ -57,11 +57,16 @@ class FirSyntheticCallGenerator(
private val checkNotNullFunction: FirSimpleFunction = generateSyntheticCheckNotNullFunction() private val checkNotNullFunction: FirSimpleFunction = generateSyntheticCheckNotNullFunction()
private val elvisFunction: FirSimpleFunction = generateSyntheticElvisFunction() private val elvisFunction: FirSimpleFunction = generateSyntheticElvisFunction()
fun generateCalleeForWhenExpression(whenExpression: FirWhenExpression, context: ResolutionContext): FirWhenExpression? { private fun assertSyntheticResolvableReferenceIsNotResolved(resolvable: FirResolvable) {
val stubReference = whenExpression.calleeReference // All synthetic calls (FirWhenExpression, FirTryExpression, FirElvisExpression, FirCheckNotNullCall)
// TODO: Investigate: assertion failed in ModularizedTest // contains FirStubReference on creation.
// assert(stubReference is FirStubReference) // generateCallee... functions below replace these references with resolved references.
if (stubReference !is FirStubReference) return null // This check ensures that we don't enter their resolve twice.
assert(resolvable.calleeReference is FirStubReference)
}
fun generateCalleeForWhenExpression(whenExpression: FirWhenExpression, context: ResolutionContext): FirWhenExpression {
assertSyntheticResolvableReferenceIsNotResolved(whenExpression)
val argumentList = buildArgumentList { val argumentList = buildArgumentList {
arguments += whenExpression.branches.map { it.result } arguments += whenExpression.branches.map { it.result }
@@ -78,8 +83,7 @@ class FirSyntheticCallGenerator(
} }
fun generateCalleeForTryExpression(tryExpression: FirTryExpression, context: ResolutionContext): FirTryExpression { fun generateCalleeForTryExpression(tryExpression: FirTryExpression, context: ResolutionContext): FirTryExpression {
val stubReference = tryExpression.calleeReference assertSyntheticResolvableReferenceIsNotResolved(tryExpression)
assert(stubReference is FirStubReference)
val argumentList = buildArgumentList { val argumentList = buildArgumentList {
with(tryExpression) { with(tryExpression) {
@@ -101,9 +105,8 @@ class FirSyntheticCallGenerator(
return tryExpression.transformCalleeReference(UpdateReference, reference) return tryExpression.transformCalleeReference(UpdateReference, reference)
} }
fun generateCalleeForCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, context: ResolutionContext): FirCheckNotNullCall? { fun generateCalleeForCheckNotNullCall(checkNotNullCall: FirCheckNotNullCall, context: ResolutionContext): FirCheckNotNullCall {
val stubReference = checkNotNullCall.calleeReference assertSyntheticResolvableReferenceIsNotResolved(checkNotNullCall)
if (stubReference !is FirStubReference) return null
val reference = generateCalleeReferenceWithCandidate( val reference = generateCalleeReferenceWithCandidate(
checkNotNullCall, checkNotNullCall,
@@ -116,8 +119,8 @@ class FirSyntheticCallGenerator(
return checkNotNullCall.transformCalleeReference(UpdateReference, reference) return checkNotNullCall.transformCalleeReference(UpdateReference, reference)
} }
fun generateCalleeForElvisExpression(elvisExpression: FirElvisExpression, context: ResolutionContext): FirElvisExpression? { fun generateCalleeForElvisExpression(elvisExpression: FirElvisExpression, context: ResolutionContext): FirElvisExpression {
if (elvisExpression.calleeReference !is FirStubReference) return null assertSyntheticResolvableReferenceIsNotResolved(elvisExpression)
val argumentList = buildArgumentList { val argumentList = buildArgumentList {
arguments += elvisExpression.lhs arguments += elvisExpression.lhs
@@ -6,8 +6,6 @@
package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve
import org.jetbrains.kotlin.fir.FirTargetElement import org.jetbrains.kotlin.fir.FirTargetElement
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock
@@ -18,7 +16,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirSyntheticCallGenerator
import org.jetbrains.kotlin.fir.resolve.transformers.FirWhenExhaustivenessTransformer import org.jetbrains.kotlin.fir.resolve.transformers.FirWhenExhaustivenessTransformer
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.fir.visitors.transformSingle
class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyResolveTransformerDispatcher) : class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyResolveTransformerDispatcher) :
@@ -85,15 +82,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
resolutionModeForBranches, resolutionModeForBranches,
) )
whenExpression = syntheticCallGenerator.generateCalleeForWhenExpression(whenExpression, resolutionContext) ?: run { whenExpression = syntheticCallGenerator.generateCalleeForWhenExpression(whenExpression, resolutionContext)
whenExpression = whenExpression.transformSingle(whenExhaustivenessTransformer, null)
dataFlowAnalyzer.exitWhenExpression(whenExpression, callCompleted = false)
whenExpression.resultType = buildErrorTypeRef {
diagnostic = ConeSimpleDiagnostic("Can't resolve when expression", DiagnosticKind.InferenceError)
}
return@withWhenSubjectType whenExpression
}
completionNeeded = true completionNeeded = true
} }
} }
@@ -268,16 +257,9 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes
) )
elvisExpression.transformRhs(transformer, resolutionModeForRhs) elvisExpression.transformRhs(transformer, resolutionModeForRhs)
var callCompleted = false val (result, callCompleted) = callCompleter.completeCall(
val result = syntheticCallGenerator.generateCalleeForElvisExpression(elvisExpression, resolutionContext)?.let { syntheticCallGenerator.generateCalleeForElvisExpression(elvisExpression, resolutionContext), data
val completed = callCompleter.completeCall(it, data) )
callCompleted = completed.callCompleted
completed.result
} ?: elvisExpression.also {
it.resultType = buildErrorTypeRef {
diagnostic = ConeSimpleDiagnostic("Can't resolve ?: operator call", DiagnosticKind.InferenceError)
}
}
var isLhsNotNull = false var isLhsNotNull = false
if (result.rhs.typeRef.coneTypeSafe<ConeKotlinType>()?.isNothing == true) { if (result.rhs.typeRef.coneTypeSafe<ConeKotlinType>()?.isNothing == true) {
@@ -954,19 +954,10 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
.transformAnnotations(transformer, ResolutionMode.ContextIndependent) .transformAnnotations(transformer, ResolutionMode.ContextIndependent)
.replaceArgumentList(checkNotNullCall.argumentList.transform(transformer, ResolutionMode.ContextDependent)) .replaceArgumentList(checkNotNullCall.argumentList.transform(transformer, ResolutionMode.ContextDependent))
var callCompleted = false val (result, callCompleted) = callCompleter.completeCall(
val result = components.syntheticCallGenerator.generateCalleeForCheckNotNullCall(checkNotNullCall, resolutionContext)?.let { components.syntheticCallGenerator.generateCalleeForCheckNotNullCall(checkNotNullCall, resolutionContext), data
val completionResult = callCompleter.completeCall(it, data) )
callCompleted = completionResult.callCompleted
completionResult.result
} ?: run {
checkNotNullCall.resultType =
buildErrorTypeRef {
diagnostic = ConeSimpleDiagnostic("Can't resolve !! operator call", DiagnosticKind.InferenceError)
}
callCompleted = true
checkNotNullCall
}
dataFlowAnalyzer.exitCheckNotNullCall(result, callCompleted) dataFlowAnalyzer.exitCheckNotNullCall(result, callCompleted)
return result return result
} }