FIR: introduce FirExpressionWithSmartcastToNull

This new kind of expression encompasses the nullability of the original
expression after null check (or equivalent `is Nothing?` check).

Unlike FirExpressionWithSmartcast, this expression won't be materialized
during conversion to backend IR. Also, Nothing? is discarded when
computing the intersection of possible types from smartcast info.
In that way, Nothing? is not used during resolution, while such
smartcast info is stored in it (and the expression kind itself).
This commit is contained in:
Jinseong Jeon
2021-04-29 23:50:22 -07:00
committed by TeamCityServer
parent 8da183e4f4
commit 8e10b5fdec
36 changed files with 370 additions and 104 deletions
@@ -277,6 +277,14 @@ class Fir2IrImplicitCastInserter(
return implicitCastOrExpression(data as IrExpression, expressionWithSmartcast.typeRef)
}
override fun visitExpressionWithSmartcastToNull(
expressionWithSmartcastToNull: FirExpressionWithSmartcastToNull,
data: IrElement
): IrElement {
// We don't want an implicit cast to Nothing?. This expression just encompasses nullability after null check.
return data
}
internal fun implicitCastFromDispatchReceiver(
original: IrExpression,
originalTypeRef: FirTypeRef,
@@ -420,6 +420,14 @@ class Fir2IrVisitor(
return implicitCastInserter.visitExpressionWithSmartcast(expressionWithSmartcast, value)
}
override fun visitExpressionWithSmartcastToNull(
expressionWithSmartcastToNull: FirExpressionWithSmartcastToNull,
data: Any?
): IrElement {
// This should not be materialized. Generate the expression with the original expression.
return convertToIrExpression(expressionWithSmartcastToNull.originalExpression)
}
override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: Any?): IrElement {
val explicitReceiverExpression = convertToIrReceiverExpression(
callableReferenceAccess.explicitReceiver, callableReferenceAccess.calleeReference, callableReferenceAccess