Skip to content

Commit b6430d0

Browse files
committed
IUO: Add ImplicitlyUnwrappedFunctionConversionExpr.
This expression node is only used when applying the results of expression type checking. It initially appears above the function reference that returns an optional that needs to be unwrapped, and then when dealing with function application we remove this and insert a node to force-unwrap the result of the function application.
1 parent b9f6405 commit b6430d0

File tree

6 files changed

+46
-0
lines changed

6 files changed

+46
-0
lines changed

include/swift/AST/Expr.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3033,6 +3033,26 @@ class CovariantReturnConversionExpr : public ImplicitConversionExpr {
30333033
}
30343034
};
30353035

3036+
/// Perform a function conversion from a function returning an
3037+
/// Optional<T> to a function returning T.
3038+
///
3039+
/// This is generated during expression type checking in places where
3040+
/// we need to force the result type of a function being called. When
3041+
/// we go to rewrite the call, we remove this node and force the
3042+
/// result of the call to the underlying function. It should never
3043+
/// exist outside of this final stage of expression type checking.
3044+
class ImplicitlyUnwrappedFunctionConversionExpr
3045+
: public ImplicitConversionExpr {
3046+
public:
3047+
ImplicitlyUnwrappedFunctionConversionExpr(Expr *subExpr, Type type)
3048+
: ImplicitConversionExpr(ExprKind::ImplicitlyUnwrappedFunctionConversion,
3049+
subExpr, type) {}
3050+
3051+
static bool classof(const Expr *E) {
3052+
return E->getKind() == ExprKind::ImplicitlyUnwrappedFunctionConversion;
3053+
}
3054+
};
3055+
30363056
/// MetatypeConversionExpr - Convert a metatype to another metatype
30373057
/// using essentially a derived-to-base conversion.
30383058
class MetatypeConversionExpr : public ImplicitConversionExpr {

include/swift/AST/ExprNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ ABSTRACT_EXPR(ImplicitConversion, Expr)
138138
EXPR(FunctionConversion, ImplicitConversionExpr)
139139
EXPR(CovariantFunctionConversion, ImplicitConversionExpr)
140140
EXPR(CovariantReturnConversion, ImplicitConversionExpr)
141+
EXPR(ImplicitlyUnwrappedFunctionConversion, ImplicitConversionExpr)
141142
EXPR(MetatypeConversion, ImplicitConversionExpr)
142143
EXPR(CollectionUpcastConversion, ImplicitConversionExpr)
143144
EXPR(Erasure, ImplicitConversionExpr)

lib/AST/ASTDumper.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,6 +2037,13 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
20372037
printRec(E->getSubExpr());
20382038
PrintWithColorRAII(OS, ParenthesisColor) << ')';
20392039
}
2040+
void visitImplicitlyUnwrappedFunctionConversionExpr(
2041+
ImplicitlyUnwrappedFunctionConversionExpr *E) {
2042+
printCommon(E, "implicitly_unwrapped_function_conversion_expr") << '\n';
2043+
printRec(E->getSubExpr());
2044+
PrintWithColorRAII(OS, ParenthesisColor) << ')';
2045+
}
2046+
20402047
void visitErasureExpr(ErasureExpr *E) {
20412048
printCommon(E, "erasure_expr") << '\n';
20422049
for (auto conf : E->getConformances()) {

lib/AST/Expr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ ConcreteDeclRef Expr::getReferencedDecl() const {
486486
PASS_THROUGH_REFERENCE(FunctionConversion, getSubExpr);
487487
PASS_THROUGH_REFERENCE(CovariantFunctionConversion, getSubExpr);
488488
PASS_THROUGH_REFERENCE(CovariantReturnConversion, getSubExpr);
489+
PASS_THROUGH_REFERENCE(ImplicitlyUnwrappedFunctionConversion, getSubExpr);
489490
PASS_THROUGH_REFERENCE(MetatypeConversion, getSubExpr);
490491
PASS_THROUGH_REFERENCE(CollectionUpcastConversion, getSubExpr);
491492
PASS_THROUGH_REFERENCE(Erasure, getSubExpr);
@@ -775,6 +776,7 @@ bool Expr::canAppendPostfixExpression(bool appendingPostfixOperator) const {
775776
case ExprKind::FunctionConversion:
776777
case ExprKind::CovariantFunctionConversion:
777778
case ExprKind::CovariantReturnConversion:
779+
case ExprKind::ImplicitlyUnwrappedFunctionConversion:
778780
case ExprKind::MetatypeConversion:
779781
case ExprKind::CollectionUpcastConversion:
780782
case ExprKind::Erasure:

lib/SILGen/SILGenApply.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,13 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
10511051
visitExpr(e);
10521052
}
10531053

1054+
void visitImplicitlyUnwrappedFunctionConversionExpr(
1055+
ImplicitlyUnwrappedFunctionConversionExpr *e) {
1056+
// These are generated for short term use in the type checker.
1057+
llvm_unreachable(
1058+
"We should not see ImplicitlyUnwrappedFunctionConversionExpr here");
1059+
}
1060+
10541061
void visitIdentityExpr(IdentityExpr *e) {
10551062
visit(e->getSubExpr());
10561063
}

lib/SILGen/SILGenExpr.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ namespace {
447447
RValue visitCovariantReturnConversionExpr(
448448
CovariantReturnConversionExpr *E,
449449
SGFContext C);
450+
RValue visitImplicitlyUnwrappedFunctionConversionExpr(
451+
ImplicitlyUnwrappedFunctionConversionExpr *E, SGFContext C);
450452
RValue visitErasureExpr(ErasureExpr *E, SGFContext C);
451453
RValue visitAnyHashableErasureExpr(AnyHashableErasureExpr *E, SGFContext C);
452454
RValue visitForcedCheckedCastExpr(ForcedCheckedCastExpr *E,
@@ -2091,6 +2093,13 @@ RValue RValueEmitter::visitCovariantReturnConversionExpr(
20912093
return RValue(SGF, e, result);
20922094
}
20932095

2096+
RValue RValueEmitter::visitImplicitlyUnwrappedFunctionConversionExpr(
2097+
ImplicitlyUnwrappedFunctionConversionExpr *e, SGFContext C) {
2098+
// These are generated for short term use in the type checker.
2099+
llvm_unreachable(
2100+
"We should not see ImplicitlyUnwrappedFunctionConversionExpr here");
2101+
}
2102+
20942103
RValue RValueEmitter::visitErasureExpr(ErasureExpr *E, SGFContext C) {
20952104
if (auto result = tryEmitAsBridgingConversion(SGF, E, false, C)) {
20962105
return RValue(SGF, E, *result);

0 commit comments

Comments
 (0)