Skip to content

Commit 1a5f00b

Browse files
committed
[AST] Add a new implicit conversion to model unsafe casts
`UnsafeCastExpr` - A special kind of conversion that performs an unsafe bitcast from one type to the other. Note that this is an unsafe operation and type-checker is allowed to use this only in a limited number of cases like: `any Sendable` -> `Any` conversions in some positions, covariant conversions of function and function result types.
1 parent c6a8cbf commit 1a5f00b

File tree

5 files changed

+32
-1
lines changed

5 files changed

+32
-1
lines changed

include/swift/AST/Expr.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3600,6 +3600,24 @@ class ActorIsolationErasureExpr : public ImplicitConversionExpr {
36003600
}
36013601
};
36023602

3603+
/// UnsafeCastExpr - A special kind of conversion that performs an unsafe
3604+
/// bitcast from one type to the other.
3605+
///
3606+
/// Note that this is an unsafe operation and type-checker is allowed to
3607+
/// use this only in a limited number of cases like: `any Sendable` -> `Any`
3608+
/// conversions in some positions, covariant conversions of function and
3609+
/// function result types.
3610+
class UnsafeCastExpr : public ImplicitConversionExpr {
3611+
public:
3612+
UnsafeCastExpr(Expr *subExpr, Type type)
3613+
: ImplicitConversionExpr(ExprKind::UnsafeCast, subExpr, type) {
3614+
}
3615+
3616+
static bool classof(const Expr *E) {
3617+
return E->getKind() == ExprKind::UnsafeCast;
3618+
}
3619+
};
3620+
36033621
/// Extracts the isolation of a dynamically isolated function value.
36043622
class ExtractFunctionIsolationExpr : public Expr {
36053623
/// The function value expression from which to extract the

include/swift/AST/ExprNodes.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ ABSTRACT_EXPR(ImplicitConversion, Expr)
191191
EXPR(LinearFunctionExtractOriginal, ImplicitConversionExpr)
192192
EXPR(LinearToDifferentiableFunction, ImplicitConversionExpr)
193193
EXPR(ActorIsolationErasure, ImplicitConversionExpr)
194-
EXPR_RANGE(ImplicitConversion, Load, ActorIsolationErasure)
194+
EXPR(UnsafeCast, ImplicitConversionExpr)
195+
EXPR_RANGE(ImplicitConversion, Load, UnsafeCast)
195196
ABSTRACT_EXPR(ExplicitCast, Expr)
196197
ABSTRACT_EXPR(CheckedCast, ExplicitCastExpr)
197198
EXPR(ForcedCheckedCast, CheckedCastExpr)

lib/AST/ASTDumper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2834,6 +2834,12 @@ class PrintExpr : public ExprVisitor<PrintExpr, void, StringRef>,
28342834
printFoot();
28352835
}
28362836

2837+
void visitUnsafeCastExpr(UnsafeCastExpr *E, StringRef label) {
2838+
printCommon(E, "unsafe_cast_expr", label);
2839+
printRec(E->getSubExpr());
2840+
printFoot();
2841+
}
2842+
28372843
void visitExtractFunctionIsolationExpr(ExtractFunctionIsolationExpr *E,
28382844
StringRef label) {
28392845
printCommon(E, "extract_function_isolation", label);

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5343,6 +5343,9 @@ void PrintAST::visitLinearToDifferentiableFunctionExpr(swift::LinearToDifferenti
53435343
void PrintAST::visitActorIsolationErasureExpr(ActorIsolationErasureExpr *expr) {
53445344
}
53455345

5346+
void PrintAST::visitUnsafeCastExpr(UnsafeCastExpr *expr) {
5347+
}
5348+
53465349
void PrintAST::visitExtractFunctionIsolationExpr(ExtractFunctionIsolationExpr *expr) {
53475350
visit(expr->getFunctionExpr());
53485351
Printer << ".isolation";

lib/AST/Expr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
444444
PASS_THROUGH_REFERENCE(UnderlyingToOpaque, getSubExpr);
445445
PASS_THROUGH_REFERENCE(Unreachable, getSubExpr);
446446
PASS_THROUGH_REFERENCE(ActorIsolationErasure, getSubExpr);
447+
PASS_THROUGH_REFERENCE(UnsafeCast, getSubExpr);
447448
NO_REFERENCE(Coerce);
448449
NO_REFERENCE(ForcedCheckedCast);
449450
NO_REFERENCE(ConditionalCheckedCast);
@@ -813,6 +814,7 @@ bool Expr::canAppendPostfixExpression(bool appendingPostfixOperator) const {
813814
case ExprKind::UnderlyingToOpaque:
814815
case ExprKind::Unreachable:
815816
case ExprKind::ActorIsolationErasure:
817+
case ExprKind::UnsafeCast:
816818
case ExprKind::TypeValue:
817819
// Implicit conversion nodes have no syntax of their own; defer to the
818820
// subexpression.
@@ -1043,6 +1045,7 @@ bool Expr::isValidParentOfTypeExpr(Expr *typeExpr) const {
10431045
case ExprKind::CurrentContextIsolation:
10441046
case ExprKind::ActorIsolationErasure:
10451047
case ExprKind::ExtractFunctionIsolation:
1048+
case ExprKind::UnsafeCast:
10461049
return false;
10471050
}
10481051

0 commit comments

Comments
 (0)