Skip to content

Commit 156aef5

Browse files
authored
Merge pull request swiftlang#75010 from hamishknight/elemental
[AST] Simplify construction of EnumElementPattern
2 parents 13dccde + fe68fab commit 156aef5

9 files changed

+102
-104
lines changed

include/swift/AST/Pattern.h

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -548,27 +548,49 @@ class EnumElementPattern : public Pattern {
548548
Pattern /*nullable*/ *SubPattern;
549549
DeclContext *DC;
550550

551-
public:
552551
EnumElementPattern(TypeExpr *ParentType, SourceLoc DotLoc,
553552
DeclNameLoc NameLoc, DeclNameRef Name,
554-
EnumElementDecl *Element, Pattern *SubPattern,
555-
DeclContext *DC)
553+
PointerUnion<EnumElementDecl *, Expr *> ElementOrOriginal,
554+
Pattern *SubPattern, DeclContext *DC)
556555
: Pattern(PatternKind::EnumElement), ParentType(ParentType),
557556
DotLoc(DotLoc), NameLoc(NameLoc), Name(Name),
558-
ElementDeclOrUnresolvedOriginalExpr(Element), SubPattern(SubPattern),
559-
DC(DC) {
560-
assert(ParentType && "Missing parent type?");
557+
ElementDeclOrUnresolvedOriginalExpr(ElementOrOriginal),
558+
SubPattern(SubPattern), DC(DC) {}
559+
560+
public:
561+
/// Create an EnumElementPattern with a parent expression, e.g `E.foo`.
562+
static EnumElementPattern *create(TypeExpr *parentExpr, SourceLoc dotLoc,
563+
DeclNameLoc nameLoc, DeclNameRef name,
564+
EnumElementDecl *decl, Pattern *subPattern,
565+
DeclContext *DC) {
566+
auto &ctx = DC->getASTContext();
567+
return new (ctx) EnumElementPattern(parentExpr, dotLoc, nameLoc, name, decl,
568+
subPattern, DC);
561569
}
562570

563571
/// Create an unresolved EnumElementPattern for a `.foo` pattern relying on
564572
/// contextual type.
565-
EnumElementPattern(SourceLoc DotLoc, DeclNameLoc NameLoc, DeclNameRef Name,
566-
Pattern *SubPattern, Expr *UnresolvedOriginalExpr,
567-
DeclContext *DC)
568-
: Pattern(PatternKind::EnumElement), ParentType(nullptr), DotLoc(DotLoc),
569-
NameLoc(NameLoc), Name(Name),
570-
ElementDeclOrUnresolvedOriginalExpr(UnresolvedOriginalExpr),
571-
SubPattern(SubPattern), DC(DC) {}
573+
static EnumElementPattern *create(SourceLoc dotLoc, DeclNameLoc nameLoc,
574+
DeclNameRef name,
575+
Expr *unresolvedOriginalExpr,
576+
Pattern *subPattern, DeclContext *DC) {
577+
auto &ctx = DC->getASTContext();
578+
return new (ctx)
579+
EnumElementPattern(/*parent*/ nullptr, dotLoc, nameLoc, name,
580+
unresolvedOriginalExpr, subPattern, DC);
581+
}
582+
583+
static EnumElementPattern *
584+
createImplicit(Type parentTy, SourceLoc dotLoc, DeclNameLoc nameLoc,
585+
EnumElementDecl *decl, Pattern *subPattern, DeclContext *DC);
586+
587+
static EnumElementPattern *createImplicit(Type parentTy,
588+
EnumElementDecl *decl,
589+
Pattern *subPattern,
590+
DeclContext *DC) {
591+
return createImplicit(parentTy, SourceLoc(), DeclNameLoc(), decl,
592+
subPattern, DC);
593+
}
572594

573595
bool hasSubPattern() const { return SubPattern; }
574596

lib/AST/Pattern.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,20 @@ void ExprPattern::updateMatchExpr(Expr *e) const {
620620

621621
MatchExprAndOperandOwnership = {e, walker.Ownership};
622622
}
623-
623+
624+
EnumElementPattern *
625+
EnumElementPattern::createImplicit(Type parentTy, SourceLoc dotLoc,
626+
DeclNameLoc nameLoc, EnumElementDecl *decl,
627+
Pattern *subPattern, DeclContext *DC) {
628+
auto &ctx = DC->getASTContext();
629+
auto *parentExpr = TypeExpr::createImplicit(parentTy, ctx);
630+
auto *P = new (ctx) EnumElementPattern(
631+
parentExpr, dotLoc, nameLoc, decl->createNameRef(), decl, subPattern, DC);
632+
P->setImplicit();
633+
P->setType(parentTy);
634+
return P;
635+
}
636+
624637
SourceLoc EnumElementPattern::getStartLoc() const {
625638
return (ParentType && !ParentType->isImplicit())
626639
? ParentType->getSourceRange().Start

lib/Sema/DerivedConformanceCodable.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -969,13 +969,10 @@ createEnumSwitch(ASTContext &C, DeclContext *DC, Expr *expr, EnumDecl *enumDecl,
969969

970970
if (caseBody) {
971971
// generate: case .<Case>:
972-
auto pat = new (C) EnumElementPattern(
973-
TypeExpr::createImplicit(
974-
DC->mapTypeIntoContext(
975-
targetElt->getParentEnum()->getDeclaredInterfaceType()),
976-
C),
977-
SourceLoc(), DeclNameLoc(), DeclNameRef(), targetElt, subpattern, DC);
978-
pat->setImplicit();
972+
auto parentTy = DC->mapTypeIntoContext(
973+
targetElt->getParentEnum()->getDeclaredInterfaceType());
974+
auto *pat = EnumElementPattern::createImplicit(parentTy, targetElt,
975+
subpattern, DC);
979976

980977
auto labelItem = CaseLabelItem(pat);
981978
auto stmt =

lib/Sema/DerivedConformanceCodingKey.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,9 @@ deriveBodyCodingKey_enum_stringValue(AbstractFunctionDecl *strValDecl, void *) {
214214
} else {
215215
SmallVector<ASTNode, 4> cases;
216216
for (auto *elt : elements) {
217-
auto *baseTE = TypeExpr::createImplicit(enumType, C);
218-
auto *pat = new (C) EnumElementPattern(baseTE, SourceLoc(), DeclNameLoc(),
219-
DeclNameRef(), elt, nullptr,
220-
/*DC*/ strValDecl);
221-
pat->setImplicit();
222-
217+
auto *pat = EnumElementPattern::createImplicit(enumType, elt,
218+
/*subPattern*/ nullptr,
219+
/*DC*/ strValDecl);
223220
auto labelItem = CaseLabelItem(pat);
224221

225222
auto *caseValue = new (C) StringLiteralExpr(elt->getNameStr(),

lib/Sema/DerivedConformanceComparable.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,23 +114,17 @@ deriveBodyComparable_enum_hasAssociatedValues_lt(AbstractFunctionDecl *ltDecl, v
114114

115115
// .<elt>(let l0, let l1, ...)
116116
SmallVector<VarDecl*, 4> lhsPayloadVars;
117-
auto lhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'l', ltDecl,
118-
lhsPayloadVars);
119-
auto *lhsBaseTE = TypeExpr::createImplicit(enumType, C);
120-
auto lhsElemPat = new (C)
121-
EnumElementPattern(lhsBaseTE, SourceLoc(), DeclNameLoc(), DeclNameRef(),
122-
elt, lhsSubpattern, /*DC*/ ltDecl);
123-
lhsElemPat->setImplicit();
117+
auto *lhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(
118+
elt, 'l', ltDecl, lhsPayloadVars);
119+
auto *lhsElemPat = EnumElementPattern::createImplicit(
120+
enumType, elt, lhsSubpattern, /*DC*/ ltDecl);
124121

125122
// .<elt>(let r0, let r1, ...)
126123
SmallVector<VarDecl*, 4> rhsPayloadVars;
127-
auto rhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'r', ltDecl,
128-
rhsPayloadVars);
129-
auto *rhsBaseTE = TypeExpr::createImplicit(enumType, C);
130-
auto rhsElemPat = new (C)
131-
EnumElementPattern(rhsBaseTE, SourceLoc(), DeclNameLoc(), DeclNameRef(),
132-
elt, rhsSubpattern, /*DC*/ ltDecl);
133-
rhsElemPat->setImplicit();
124+
auto *rhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(
125+
elt, 'r', ltDecl, rhsPayloadVars);
126+
auto *rhsElemPat = EnumElementPattern::createImplicit(
127+
enumType, elt, rhsSubpattern, /*DC*/ ltDecl);
134128

135129
auto hasBoundDecls = !lhsPayloadVars.empty();
136130
std::optional<MutableArrayRef<VarDecl *>> caseBodyVarDecls;

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -181,23 +181,17 @@ deriveBodyEquatable_enum_hasAssociatedValues_eq(AbstractFunctionDecl *eqDecl,
181181

182182
// .<elt>(let l0, let l1, ...)
183183
SmallVector<VarDecl*, 3> lhsPayloadVars;
184-
auto lhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'l', eqDecl,
185-
lhsPayloadVars);
186-
auto *lhsBaseTE = TypeExpr::createImplicit(enumType, C);
187-
auto lhsElemPat = new (C)
188-
EnumElementPattern(lhsBaseTE, SourceLoc(), DeclNameLoc(), DeclNameRef(),
189-
elt, lhsSubpattern, /*DC*/ eqDecl);
190-
lhsElemPat->setImplicit();
184+
auto *lhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(
185+
elt, 'l', eqDecl, lhsPayloadVars);
186+
auto *lhsElemPat = EnumElementPattern::createImplicit(
187+
enumType, elt, lhsSubpattern, /*DC*/ eqDecl);
191188

192189
// .<elt>(let r0, let r1, ...)
193190
SmallVector<VarDecl*, 3> rhsPayloadVars;
194-
auto rhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'r', eqDecl,
195-
rhsPayloadVars);
196-
auto *rhsBaseTE = TypeExpr::createImplicit(enumType, C);
197-
auto rhsElemPat = new (C)
198-
EnumElementPattern(rhsBaseTE, SourceLoc(), DeclNameLoc(), DeclNameRef(),
199-
elt, rhsSubpattern, /*DC*/ eqDecl);
200-
rhsElemPat->setImplicit();
191+
auto *rhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(
192+
elt, 'r', eqDecl, rhsPayloadVars);
193+
auto *rhsElemPat = EnumElementPattern::createImplicit(
194+
enumType, elt, rhsSubpattern, /*DC*/ eqDecl);
201195

202196
auto hasBoundDecls = !lhsPayloadVars.empty();
203197
std::optional<MutableArrayRef<VarDecl *>> caseBodyVarDecls;
@@ -709,11 +703,8 @@ deriveBodyHashable_enum_hasAssociatedValues_hashInto(
709703

710704
auto payloadPattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'a', hashIntoDecl,
711705
payloadVars);
712-
auto pat = new (C)
713-
EnumElementPattern(TypeExpr::createImplicit(enumType, C), SourceLoc(),
714-
DeclNameLoc(), DeclNameRef(elt->getBaseIdentifier()),
715-
elt, payloadPattern, /*DC*/ hashIntoDecl);
716-
pat->setImplicit();
706+
auto *pat = EnumElementPattern::createImplicit(
707+
enumType, elt, payloadPattern, /*DC*/ hashIntoDecl);
717708

718709
auto labelItem = CaseLabelItem(pat);
719710

lib/Sema/DerivedConformanceRawRepresentable.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,8 @@ deriveBodyRawRepresentable_raw(AbstractFunctionDecl *toRawDecl, void *) {
113113

114114
SmallVector<ASTNode, 4> cases;
115115
for (auto elt : enumDecl->getAllElements()) {
116-
auto pat = new (C)
117-
EnumElementPattern(TypeExpr::createImplicit(enumType, C), SourceLoc(),
118-
DeclNameLoc(), DeclNameRef(), elt, nullptr,
119-
/*DC*/ toRawDecl);
120-
pat->setImplicit();
116+
auto *pat = EnumElementPattern::createImplicit(
117+
enumType, elt, /*subPattern*/ nullptr, /*DC*/ toRawDecl);
121118

122119
auto labelItem = CaseLabelItem(pat);
123120

lib/Sema/DerivedConformances.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -785,12 +785,8 @@ DeclRefExpr *DerivedConformance::convertEnumToIndex(SmallVectorImpl<ASTNode> &st
785785
}
786786

787787
// generate: case .<Case>:
788-
auto pat = new (C)
789-
EnumElementPattern(TypeExpr::createImplicit(enumType, C), SourceLoc(),
790-
DeclNameLoc(), DeclNameRef(), elt, nullptr,
791-
/*DC*/ funcDecl);
792-
pat->setImplicit();
793-
pat->setType(enumType);
788+
auto *pat = EnumElementPattern::createImplicit(
789+
enumType, elt, /*subPattern*/ nullptr, /*DC*/ funcDecl);
794790

795791
auto labelItem = CaseLabelItem(pat);
796792

@@ -947,12 +943,8 @@ CaseStmt *DerivedConformance::unavailableEnumElementCaseStmt(
947943

948944
auto createElementPattern = [&]() -> EnumElementPattern * {
949945
// .<elt>
950-
EnumElementPattern *eltPattern = new (C) EnumElementPattern(
951-
TypeExpr::createImplicit(enumType, C), SourceLoc(), DeclNameLoc(),
952-
DeclNameRef(elt->getBaseIdentifier()), elt, nullptr, /*DC*/ parentDC);
953-
eltPattern->setImplicit();
954-
eltPattern->setType(enumType);
955-
return eltPattern;
946+
return EnumElementPattern::createImplicit(
947+
enumType, elt, /*subPattern*/ nullptr, /*DC*/ parentDC);
956948
};
957949

958950
Pattern *labelItemPattern;

lib/Sema/TypeCheckPattern.cpp

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,9 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
450450
if (ume->getName().getBaseName().isSpecial())
451451
return nullptr;
452452

453-
return new (Context) EnumElementPattern(ume->getDotLoc(), ume->getNameLoc(),
454-
ume->getName(), nullptr, ume, DC);
453+
return EnumElementPattern::create(ume->getDotLoc(), ume->getNameLoc(),
454+
ume->getName(), ume,
455+
/*subPattern*/ nullptr, DC);
455456
}
456457

457458
// Member syntax 'T.Element' forms a pattern if 'T' is an enum and the
@@ -491,9 +492,9 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
491492
auto *base =
492493
TypeExpr::createForMemberDecl(repr, ude->getNameLoc(), enumDecl);
493494
base->setType(MetatypeType::get(ty));
494-
return new (Context)
495-
EnumElementPattern(base, ude->getDotLoc(), ude->getNameLoc(),
496-
ude->getName(), referencedElement, nullptr, DC);
495+
return EnumElementPattern::create(base, ude->getDotLoc(), ude->getNameLoc(),
496+
ude->getName(), referencedElement,
497+
/*subPattern*/ nullptr, DC);
497498
}
498499

499500
// A DeclRef 'E' that refers to an enum element forms an EnumElementPattern.
@@ -506,9 +507,9 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
506507
auto enumTy = elt->getParentEnum()->getDeclaredTypeInContext();
507508
auto *base = TypeExpr::createImplicit(enumTy, Context);
508509

509-
return new (Context)
510-
EnumElementPattern(base, SourceLoc(), de->getNameLoc(),
511-
elt->createNameRef(), elt, nullptr, DC);
510+
return EnumElementPattern::create(base, SourceLoc(), de->getNameLoc(),
511+
elt->createNameRef(), elt,
512+
/*subPattern*/ nullptr, DC);
512513
}
513514
Pattern *visitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *ude) {
514515
// FIXME: This shouldn't be needed. It is only necessary because of the
@@ -523,9 +524,9 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
523524
auto enumTy = enumDecl->getDeclaredTypeInContext();
524525
auto *base = TypeExpr::createImplicit(enumTy, Context);
525526

526-
return new (Context)
527-
EnumElementPattern(base, SourceLoc(), ude->getNameLoc(),
528-
ude->getName(), referencedElement, nullptr, DC);
527+
return EnumElementPattern::create(base, SourceLoc(), ude->getNameLoc(),
528+
ude->getName(), referencedElement,
529+
/*subPattern*/ nullptr, DC);
529530
}
530531

531532

@@ -617,9 +618,9 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
617618
assert(!repr->hasGenericArgList() && "should be handled above");
618619

619620
auto *subPattern = composeTupleOrParenPattern(ce->getArgs());
620-
return new (Context) EnumElementPattern(
621-
baseTE, SourceLoc(), repr->getNameLoc(), repr->getNameRef(),
622-
referencedElement, subPattern, DC);
621+
return EnumElementPattern::create(baseTE, SourceLoc(), repr->getNameLoc(),
622+
repr->getNameRef(), referencedElement,
623+
subPattern, DC);
623624
}
624625
};
625626

@@ -1061,13 +1062,9 @@ NullablePtr<Pattern> TypeChecker::trySimplifyExprPattern(ExprPattern *EP,
10611062
if (auto *NLE = dyn_cast<NilLiteralExpr>(EP->getSubExpr())) {
10621063
if (patternTy->getOptionalObjectType()) {
10631064
auto *NoneEnumElement = ctx.getOptionalNoneDecl();
1064-
auto *BaseTE = TypeExpr::createImplicit(patternTy, ctx);
1065-
auto *EEP = new (ctx)
1066-
EnumElementPattern(BaseTE, NLE->getLoc(), DeclNameLoc(NLE->getLoc()),
1067-
NoneEnumElement->createNameRef(), NoneEnumElement,
1068-
nullptr, EP->getDeclContext());
1069-
EEP->setType(patternTy);
1070-
return EEP;
1065+
return EnumElementPattern::createImplicit(
1066+
patternTy, NLE->getLoc(), DeclNameLoc(NLE->getLoc()), NoneEnumElement,
1067+
/*subPattern*/ nullptr, EP->getDeclContext());
10711068
} else {
10721069
// ...but for non-optional types it can never match! Diagnose it.
10731070
ctx.Diags
@@ -1388,14 +1385,12 @@ Pattern *TypeChecker::coercePatternToType(
13881385
if (numExtraOptionals > 0) {
13891386
Pattern *sub = IP;
13901387
auto extraOpts =
1391-
llvm::drop_begin(inputTypeOptionals, castTypeOptionals.size());
1388+
llvm::drop_end(inputTypeOptionals, castTypeOptionals.size());
13921389
for (auto extraOptTy : llvm::reverse(extraOpts)) {
13931390
auto some = Context.getOptionalSomeDecl();
1394-
auto *base = TypeExpr::createImplicit(extraOptTy, Context);
1395-
sub = new (Context) EnumElementPattern(
1396-
base, IP->getStartLoc(), DeclNameLoc(IP->getEndLoc()),
1397-
some->createNameRef(), nullptr, sub, dc);
1398-
sub->setImplicit();
1391+
sub = EnumElementPattern::createImplicit(extraOptTy, IP->getStartLoc(),
1392+
DeclNameLoc(IP->getEndLoc()),
1393+
some, sub, dc);
13991394
}
14001395

14011396
P = sub;

0 commit comments

Comments
 (0)