FIR: assume a lambda returns Unit if it ends with a non-expression
While it is theoretically useful to know that `{ while(true) {} }`
returns Nothing, CFG node deadness is not precise enough to do that: if
the entire lambda is dead, it's no longer possible to find out whether
the loop is terminating. Besides, `while (true)` and `if (true)` are
pretty much the only constructs like that anyway.
Note that this commit does not affect resolution for lambdas that end in
a Nothing-returning expression, e.g. `throw`.
This commit is contained in:
@@ -13,6 +13,9 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.PersistentFlow
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitNothingTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.isNothing
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
@@ -891,17 +894,18 @@ class AnnotationExitNode(owner: ControlFlowGraph, override val fir: FirAnnotatio
|
||||
|
||||
// ----------------------------------- Stub -----------------------------------
|
||||
|
||||
object FirStub : FirElement {
|
||||
object FirStub : FirExpression() {
|
||||
override val source: KtSourceElement? get() = null
|
||||
override val typeRef: FirTypeRef = FirImplicitNothingTypeRef(null)
|
||||
override val annotations: List<FirAnnotation> get() = listOf()
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
|
||||
return this
|
||||
}
|
||||
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirExpression = this
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement = this
|
||||
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) { assert(newAnnotations.isEmpty()) }
|
||||
override fun replaceTypeRef(newTypeRef: FirTypeRef) { assert(newTypeRef.isNothing) }
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------- Smart-cast node -----------------------------------
|
||||
|
||||
class SmartCastExpressionExitNode(owner: ControlFlowGraph, override val fir: FirSmartCastExpression, level: Int, id: Int) : CFGNode<FirSmartCastExpression>(owner, level, id) {
|
||||
|
||||
Reference in New Issue
Block a user