Skip to content

Commit 2a6bad2

Browse files
authored
Merge pull request #33049 from CodaFi/casting-call
[NFC] Stash Syntactic Information in EnumIsCaseExpr
2 parents 303310f + cb82a46 commit 2a6bad2

File tree

4 files changed

+38
-39
lines changed

4 files changed

+38
-39
lines changed

include/swift/AST/Expr.h

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4704,7 +4704,7 @@ class ForcedCheckedCastExpr final : public CheckedCastExpr {
47044704

47054705
/// Represents an explicit conditional checked cast, which converts
47064706
/// from a type to some subtype and produces an Optional value, which will be
4707-
/// .Some(x) if the cast succeeds, or .None if the cast fails.
4707+
/// .some(x) if the cast succeeds, or .none if the cast fails.
47084708
/// Spelled 'a as? T' and produces a value of type 'T?'.
47094709
class ConditionalCheckedCastExpr final : public CheckedCastExpr {
47104710
SourceLoc QuestionLoc;
@@ -4722,9 +4722,6 @@ class ConditionalCheckedCastExpr final : public CheckedCastExpr {
47224722
static ConditionalCheckedCastExpr *createImplicit(ASTContext &ctx, Expr *sub,
47234723
Type castTy);
47244724

4725-
static ConditionalCheckedCastExpr *
4726-
createImplicit(ASTContext &ctx, Expr *sub, TypeRepr *tyRepr, Type castTy);
4727-
47284725
/// Retrieve the location of the '?' that follows 'as'.
47294726
SourceLoc getQuestionLoc() const { return QuestionLoc; }
47304727

@@ -4911,20 +4908,21 @@ class IfExpr : public Expr {
49114908
/// a particular case.
49124909
class EnumIsCaseExpr : public Expr {
49134910
Expr *SubExpr;
4911+
TypeRepr *CaseRepr;
49144912
EnumElementDecl *Element;
49154913

49164914
public:
4917-
EnumIsCaseExpr(Expr *SubExpr, EnumElementDecl *Element)
4918-
: Expr(ExprKind::EnumIsCase, /*implicit*/ true),
4919-
SubExpr(SubExpr), Element(Element)
4920-
{}
4921-
4915+
EnumIsCaseExpr(Expr *SubExpr, TypeRepr *CaseRepr, EnumElementDecl *Element)
4916+
: Expr(ExprKind::EnumIsCase, /*implicit*/ true), SubExpr(SubExpr),
4917+
CaseRepr(CaseRepr), Element(Element) {}
4918+
49224919
Expr *getSubExpr() const { return SubExpr; }
49234920
void setSubExpr(Expr *e) { SubExpr = e; }
4924-
4921+
4922+
TypeRepr *getCaseTypeRepr() const { return CaseRepr; }
4923+
49254924
EnumElementDecl *getEnumElement() const { return Element; }
4926-
void setEnumElement(EnumElementDecl *elt) { Element = elt; }
4927-
4925+
49284926
SourceLoc getLoc() const { return SubExpr->getLoc(); }
49294927
SourceLoc getStartLoc() const { return SubExpr->getStartLoc(); }
49304928
SourceLoc getEndLoc() const { return SubExpr->getEndLoc(); }

lib/AST/ASTWalker.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,11 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
951951
return nullptr;
952952
E->setSubExpr(Sub);
953953
}
954-
954+
955+
if (auto *typerepr = E->getCaseTypeRepr())
956+
if (doIt(typerepr))
957+
return nullptr;
958+
955959
return E;
956960
}
957961

lib/AST/Expr.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,17 +1808,6 @@ ConditionalCheckedCastExpr::createImplicit(ASTContext &ctx, Expr *sub,
18081808
return expr;
18091809
}
18101810

1811-
ConditionalCheckedCastExpr *
1812-
ConditionalCheckedCastExpr::createImplicit(ASTContext &ctx, Expr *sub,
1813-
TypeRepr *tyRepr, Type castTy) {
1814-
auto *const expr = new (ctx) ConditionalCheckedCastExpr(
1815-
sub, SourceLoc(), SourceLoc(), new (ctx) TypeExpr(tyRepr));
1816-
expr->setType(OptionalType::get(castTy));
1817-
expr->setImplicit();
1818-
expr->setCastType(castTy);
1819-
return expr;
1820-
}
1821-
18221811
IsExpr *IsExpr::create(ASTContext &ctx, SourceLoc isLoc, TypeRepr *tyRepr) {
18231812
return new (ctx) IsExpr(nullptr, isLoc, new (ctx) TypeExpr(tyRepr));
18241813
}

lib/Sema/CSApply.cpp

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3574,12 +3574,14 @@ namespace {
35743574
castKind == CheckedCastKind::ArrayDowncast ||
35753575
castKind == CheckedCastKind::DictionaryDowncast ||
35763576
castKind == CheckedCastKind::SetDowncast) {
3577-
auto *const cast = ConditionalCheckedCastExpr::createImplicit(
3578-
ctx, sub, castTypeRepr, toType);
3577+
auto *const cast =
3578+
ConditionalCheckedCastExpr::createImplicit(ctx, sub, toType);
3579+
cast->setType(OptionalType::get(toType));
3580+
cast->setCastType(toType);
35793581
cs.setType(cast, cast->getType());
35803582

35813583
// Type-check this conditional case.
3582-
Expr *result = handleConditionalCheckedCastExpr(cast, true);
3584+
Expr *result = handleConditionalCheckedCastExpr(cast, castTypeRepr);
35833585
if (!result)
35843586
return nullptr;
35853587

@@ -3588,7 +3590,8 @@ namespace {
35883590

35893591
// Match the optional value against its `Some` case.
35903592
auto *someDecl = ctx.getOptionalSomeDecl();
3591-
auto isSomeExpr = new (ctx) EnumIsCaseExpr(result, someDecl);
3593+
auto isSomeExpr =
3594+
new (ctx) EnumIsCaseExpr(result, castTypeRepr, someDecl);
35923595
auto boolDecl = ctx.getBoolDecl();
35933596

35943597
if (!boolDecl) {
@@ -4010,40 +4013,45 @@ namespace {
40104013
}
40114014

40124015
Expr *visitConditionalCheckedCastExpr(ConditionalCheckedCastExpr *expr) {
4016+
// Simplify and update the type we're casting to.
4017+
auto *const castTypeRepr = expr->getCastTypeRepr();
4018+
const auto toType = simplifyType(cs.getType(castTypeRepr));
4019+
expr->setCastType(toType);
4020+
cs.setType(castTypeRepr, toType);
4021+
40134022
// If we need to insert a force-unwrap for coercions of the form
40144023
// 'as! T!', do so now.
40154024
if (hasForcedOptionalResult(expr)) {
4016-
auto *coerced = handleConditionalCheckedCastExpr(expr);
4025+
auto *coerced = handleConditionalCheckedCastExpr(expr, castTypeRepr);
40174026
if (!coerced)
40184027
return nullptr;
40194028

40204029
return coerceImplicitlyUnwrappedOptionalToValue(
40214030
coerced, cs.getType(coerced)->getOptionalObjectType());
40224031
}
40234032

4024-
return handleConditionalCheckedCastExpr(expr);
4033+
return handleConditionalCheckedCastExpr(expr, castTypeRepr);
40254034
}
40264035

40274036
Expr *handleConditionalCheckedCastExpr(ConditionalCheckedCastExpr *expr,
4028-
bool isInsideIsExpr = false) {
4037+
TypeRepr *castTypeRepr) {
4038+
assert(castTypeRepr &&
4039+
"cast requires TypeRepr; implicit casts are superfluous");
4040+
40294041
// The subexpression is always an rvalue.
40304042
auto &ctx = cs.getASTContext();
40314043
auto sub = cs.coerceToRValue(expr->getSubExpr());
40324044
expr->setSubExpr(sub);
40334045

40344046
// Simplify and update the type we're casting to.
4035-
auto *const castTypeRepr = expr->getCastTypeRepr();
4036-
40374047
const auto fromType = cs.getType(sub);
4038-
const auto toType = simplifyType(cs.getType(castTypeRepr));
4039-
expr->setCastType(toType);
4040-
cs.setType(castTypeRepr, toType);
4048+
const auto toType = expr->getCastType();
40414049

40424050
bool isSubExprLiteral = isa<LiteralExpr>(sub);
40434051
auto castContextKind =
4044-
(SuppressDiagnostics || isInsideIsExpr || isSubExprLiteral)
4045-
? CheckedCastContextKind::None
4046-
: CheckedCastContextKind::ConditionalCast;
4052+
(SuppressDiagnostics || expr->isImplicit() || isSubExprLiteral)
4053+
? CheckedCastContextKind::None
4054+
: CheckedCastContextKind::ConditionalCast;
40474055

40484056
auto castKind = TypeChecker::typeCheckCheckedCast(
40494057
fromType, toType, castContextKind, cs.DC, expr->getLoc(), sub,

0 commit comments

Comments
 (0)