Skip to content

Commit 23d7091

Browse files
committed
EnumElementExprPatternRequest
1 parent e37d855 commit 23d7091

11 files changed

+80
-38
lines changed

include/swift/AST/Pattern.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -508,25 +508,29 @@ class EnumElementPattern : public Pattern {
508508
DeclNameRef Name;
509509
PointerUnion<EnumElementDecl *, Expr*> ElementDeclOrUnresolvedOriginalExpr;
510510
Pattern /*nullable*/ *SubPattern;
511+
DeclContext *DC;
511512

512513
public:
513514
EnumElementPattern(TypeExpr *ParentType, SourceLoc DotLoc,
514515
DeclNameLoc NameLoc, DeclNameRef Name,
515-
EnumElementDecl *Element, Pattern *SubPattern)
516+
EnumElementDecl *Element, Pattern *SubPattern,
517+
DeclContext *DC)
516518
: Pattern(PatternKind::EnumElement), ParentType(ParentType),
517519
DotLoc(DotLoc), NameLoc(NameLoc), Name(Name),
518-
ElementDeclOrUnresolvedOriginalExpr(Element), SubPattern(SubPattern) {
520+
ElementDeclOrUnresolvedOriginalExpr(Element), SubPattern(SubPattern),
521+
DC(DC) {
519522
assert(ParentType && "Missing parent type?");
520523
}
521524

522525
/// Create an unresolved EnumElementPattern for a `.foo` pattern relying on
523526
/// contextual type.
524527
EnumElementPattern(SourceLoc DotLoc, DeclNameLoc NameLoc, DeclNameRef Name,
525-
Pattern *SubPattern, Expr *UnresolvedOriginalExpr)
528+
Pattern *SubPattern, Expr *UnresolvedOriginalExpr,
529+
DeclContext *DC)
526530
: Pattern(PatternKind::EnumElement), ParentType(nullptr), DotLoc(DotLoc),
527531
NameLoc(NameLoc), Name(Name),
528532
ElementDeclOrUnresolvedOriginalExpr(UnresolvedOriginalExpr),
529-
SubPattern(SubPattern) {}
533+
SubPattern(SubPattern), DC(DC) {}
530534

531535
bool hasSubPattern() const { return SubPattern; }
532536

@@ -540,6 +544,8 @@ class EnumElementPattern : public Pattern {
540544

541545
void setSubPattern(Pattern *p) { SubPattern = p; }
542546

547+
DeclContext *getDeclContext() const { return DC; }
548+
543549
DeclNameRef getName() const { return Name; }
544550

545551
EnumElementDecl *getElementDecl() const {

include/swift/AST/TypeCheckRequests.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,6 +2265,27 @@ class ExprPatternMatchRequest
22652265
void cacheResult(ExprPatternMatchResult result) const;
22662266
};
22672267

2268+
/// Creates a corresponding ExprPattern from the original Expr of an
2269+
/// EnumElementPattern.
2270+
class EnumElementExprPatternRequest
2271+
: public SimpleRequest<EnumElementExprPatternRequest,
2272+
ExprPattern *(const EnumElementPattern *),
2273+
RequestFlags::Cached> {
2274+
public:
2275+
using SimpleRequest::SimpleRequest;
2276+
2277+
private:
2278+
friend SimpleRequest;
2279+
2280+
// Evaluation.
2281+
ExprPattern *evaluate(Evaluator &evaluator,
2282+
const EnumElementPattern *EEP) const;
2283+
2284+
public:
2285+
// Cached.
2286+
bool isCached() const { return true; }
2287+
};
2288+
22682289
class InterfaceTypeRequest :
22692290
public SimpleRequest<InterfaceTypeRequest,
22702291
Type (ValueDecl *),

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ SWIFT_REQUEST(TypeChecker, NamingPatternRequest,
231231
SWIFT_REQUEST(TypeChecker, ExprPatternMatchRequest,
232232
ExprPatternMatchResult(const ExprPattern *),
233233
SeparatelyCached, NoLocationInfo)
234+
SWIFT_REQUEST(TypeChecker, EnumElementExprPatternRequest,
235+
ExprPattern *(const EnumElementPattern *),
236+
Cached, NoLocationInfo)
234237
SWIFT_REQUEST(TypeChecker, OpaqueReadOwnershipRequest,
235238
OpaqueReadOwnership(AbstractStorageDecl *), SeparatelyCached,
236239
NoLocationInfo)

lib/Sema/CSSimplify.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9921,13 +9921,12 @@ static bool inferEnumMemberThroughTildeEqualsOperator(
99219921
if (!pattern->hasUnresolvedOriginalExpr())
99229922
return true;
99239923

9924-
auto &DC = cs.DC;
9924+
auto *DC = pattern->getDeclContext();
99259925
auto &ctx = cs.getASTContext();
99269926

9927-
// Slots for expression and variable are going to be filled via
9928-
// synthesizing ~= operator application.
9929-
auto *EP = ExprPattern::createResolved(
9930-
ctx, pattern->getUnresolvedOriginalExpr(), DC);
9927+
// Retrieve a corresponding ExprPattern which we can solve with ~=.
9928+
auto *EP =
9929+
llvm::cantFail(ctx.evaluator(EnumElementExprPatternRequest{pattern}));
99319930

99329931
// result of ~= operator is always a `Bool`.
99339932
auto *matchCall = EP->getMatchExpr();

lib/Sema/DerivedConformanceCodable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ createEnumSwitch(ASTContext &C, DeclContext *DC, Expr *expr, EnumDecl *enumDecl,
976976
DC->mapTypeIntoContext(
977977
targetElt->getParentEnum()->getDeclaredInterfaceType()),
978978
C),
979-
SourceLoc(), DeclNameLoc(), DeclNameRef(), targetElt, subpattern);
979+
SourceLoc(), DeclNameLoc(), DeclNameRef(), targetElt, subpattern, DC);
980980
pat->setImplicit();
981981

982982
auto labelItem = CaseLabelItem(pat);

lib/Sema/DerivedConformanceCodingKey.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ deriveBodyCodingKey_enum_stringValue(AbstractFunctionDecl *strValDecl, void *) {
214214
for (auto *elt : elements) {
215215
auto *baseTE = TypeExpr::createImplicit(enumType, C);
216216
auto *pat = new (C) EnumElementPattern(baseTE, SourceLoc(), DeclNameLoc(),
217-
DeclNameRef(), elt, nullptr);
217+
DeclNameRef(), elt, nullptr,
218+
/*DC*/ strValDecl);
218219
pat->setImplicit();
219220

220221
auto labelItem = CaseLabelItem(pat);

lib/Sema/DerivedConformanceComparable.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,19 +116,19 @@ deriveBodyComparable_enum_hasAssociatedValues_lt(AbstractFunctionDecl *ltDecl, v
116116
auto lhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'l', ltDecl,
117117
lhsPayloadVars);
118118
auto *lhsBaseTE = TypeExpr::createImplicit(enumType, C);
119-
auto lhsElemPat =
120-
new (C) EnumElementPattern(lhsBaseTE, SourceLoc(), DeclNameLoc(),
121-
DeclNameRef(), elt, lhsSubpattern);
119+
auto lhsElemPat = new (C)
120+
EnumElementPattern(lhsBaseTE, SourceLoc(), DeclNameLoc(), DeclNameRef(),
121+
elt, lhsSubpattern, /*DC*/ ltDecl);
122122
lhsElemPat->setImplicit();
123123

124124
// .<elt>(let r0, let r1, ...)
125125
SmallVector<VarDecl*, 4> rhsPayloadVars;
126126
auto rhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'r', ltDecl,
127127
rhsPayloadVars);
128128
auto *rhsBaseTE = TypeExpr::createImplicit(enumType, C);
129-
auto rhsElemPat =
130-
new (C) EnumElementPattern(rhsBaseTE, SourceLoc(), DeclNameLoc(),
131-
DeclNameRef(), elt, rhsSubpattern);
129+
auto rhsElemPat = new (C)
130+
EnumElementPattern(rhsBaseTE, SourceLoc(), DeclNameLoc(), DeclNameRef(),
131+
elt, rhsSubpattern, /*DC*/ ltDecl);
132132
rhsElemPat->setImplicit();
133133

134134
auto hasBoundDecls = !lhsPayloadVars.empty();

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -181,19 +181,19 @@ deriveBodyEquatable_enum_hasAssociatedValues_eq(AbstractFunctionDecl *eqDecl,
181181
auto lhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'l', eqDecl,
182182
lhsPayloadVars);
183183
auto *lhsBaseTE = TypeExpr::createImplicit(enumType, C);
184-
auto lhsElemPat =
185-
new (C) EnumElementPattern(lhsBaseTE, SourceLoc(), DeclNameLoc(),
186-
DeclNameRef(), elt, lhsSubpattern);
184+
auto lhsElemPat = new (C)
185+
EnumElementPattern(lhsBaseTE, SourceLoc(), DeclNameLoc(), DeclNameRef(),
186+
elt, lhsSubpattern, /*DC*/ eqDecl);
187187
lhsElemPat->setImplicit();
188188

189189
// .<elt>(let r0, let r1, ...)
190190
SmallVector<VarDecl*, 3> rhsPayloadVars;
191191
auto rhsSubpattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'r', eqDecl,
192192
rhsPayloadVars);
193193
auto *rhsBaseTE = TypeExpr::createImplicit(enumType, C);
194-
auto rhsElemPat =
195-
new (C) EnumElementPattern(rhsBaseTE, SourceLoc(), DeclNameLoc(),
196-
DeclNameRef(), elt, rhsSubpattern);
194+
auto rhsElemPat = new (C)
195+
EnumElementPattern(rhsBaseTE, SourceLoc(), DeclNameLoc(), DeclNameRef(),
196+
elt, rhsSubpattern, /*DC*/ eqDecl);
197197
rhsElemPat->setImplicit();
198198

199199
auto hasBoundDecls = !lhsPayloadVars.empty();
@@ -702,9 +702,10 @@ deriveBodyHashable_enum_hasAssociatedValues_hashInto(
702702

703703
auto payloadPattern = DerivedConformance::enumElementPayloadSubpattern(elt, 'a', hashIntoDecl,
704704
payloadVars);
705-
auto pat = new (C) EnumElementPattern(
706-
TypeExpr::createImplicit(enumType, C), SourceLoc(), DeclNameLoc(),
707-
DeclNameRef(elt->getBaseIdentifier()), elt, payloadPattern);
705+
auto pat = new (C)
706+
EnumElementPattern(TypeExpr::createImplicit(enumType, C), SourceLoc(),
707+
DeclNameLoc(), DeclNameRef(elt->getBaseIdentifier()),
708+
elt, payloadPattern, /*DC*/ hashIntoDecl);
708709
pat->setImplicit();
709710

710711
auto labelItem = CaseLabelItem(pat);

lib/Sema/DerivedConformanceRawRepresentable.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ deriveBodyRawRepresentable_raw(AbstractFunctionDecl *toRawDecl, void *) {
114114
for (auto elt : enumDecl->getAllElements()) {
115115
auto pat = new (C)
116116
EnumElementPattern(TypeExpr::createImplicit(enumType, C), SourceLoc(),
117-
DeclNameLoc(), DeclNameRef(), elt, nullptr);
117+
DeclNameLoc(), DeclNameRef(), elt, nullptr,
118+
/*DC*/ toRawDecl);
118119
pat->setImplicit();
119120

120121
auto labelItem = CaseLabelItem(pat);

lib/Sema/DerivedConformances.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,8 @@ DeclRefExpr *DerivedConformance::convertEnumToIndex(SmallVectorImpl<ASTNode> &st
737737
// generate: case .<Case>:
738738
auto pat = new (C)
739739
EnumElementPattern(TypeExpr::createImplicit(enumType, C), SourceLoc(),
740-
DeclNameLoc(), DeclNameRef(), elt, nullptr);
740+
DeclNameLoc(), DeclNameRef(), elt, nullptr,
741+
/*DC*/ funcDecl);
741742
pat->setImplicit();
742743
pat->setType(enumType);
743744

lib/Sema/TypeCheckPattern.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -439,9 +439,8 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
439439
if (ume->getName().getBaseName().isSpecial())
440440
return nullptr;
441441

442-
return new (Context)
443-
EnumElementPattern(ume->getDotLoc(), ume->getNameLoc(), ume->getName(),
444-
nullptr, ume);
442+
return new (Context) EnumElementPattern(ume->getDotLoc(), ume->getNameLoc(),
443+
ume->getName(), nullptr, ume, DC);
445444
}
446445

447446
// Member syntax 'T.Element' forms a pattern if 'T' is an enum and the
@@ -483,7 +482,7 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
483482
base->setType(MetatypeType::get(ty));
484483
return new (Context)
485484
EnumElementPattern(base, ude->getDotLoc(), ude->getNameLoc(),
486-
ude->getName(), referencedElement, nullptr);
485+
ude->getName(), referencedElement, nullptr, DC);
487486
}
488487

489488
// A DeclRef 'E' that refers to an enum element forms an EnumElementPattern.
@@ -496,8 +495,9 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
496495
auto enumTy = elt->getParentEnum()->getDeclaredTypeInContext();
497496
auto *base = TypeExpr::createImplicit(enumTy, Context);
498497

499-
return new (Context) EnumElementPattern(base, SourceLoc(), de->getNameLoc(),
500-
elt->createNameRef(), elt, nullptr);
498+
return new (Context)
499+
EnumElementPattern(base, SourceLoc(), de->getNameLoc(),
500+
elt->createNameRef(), elt, nullptr, DC);
501501
}
502502
Pattern *visitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *ude) {
503503
// FIXME: This shouldn't be needed. It is only necessary because of the
@@ -514,7 +514,7 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
514514

515515
return new (Context)
516516
EnumElementPattern(base, SourceLoc(), ude->getNameLoc(),
517-
ude->getName(), referencedElement, nullptr);
517+
ude->getName(), referencedElement, nullptr, DC);
518518
}
519519

520520

@@ -614,7 +614,7 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
614614
auto *subPattern = composeTupleOrParenPattern(ce->getArgs());
615615
return new (Context) EnumElementPattern(
616616
baseTE, SourceLoc(), tailComponent->getNameLoc(),
617-
tailComponent->getNameRef(), referencedElement, subPattern);
617+
tailComponent->getNameRef(), referencedElement, subPattern, DC);
618618
}
619619
};
620620

@@ -791,6 +791,15 @@ ExprPatternMatchRequest::evaluate(Evaluator &evaluator,
791791
return {matchVar, matchCall};
792792
}
793793

794+
ExprPattern *
795+
EnumElementExprPatternRequest::evaluate(Evaluator &evaluator,
796+
const EnumElementPattern *EEP) const {
797+
assert(EEP->hasUnresolvedOriginalExpr());
798+
auto *DC = EEP->getDeclContext();
799+
return ExprPattern::createResolved(DC->getASTContext(),
800+
EEP->getUnresolvedOriginalExpr(), DC);
801+
}
802+
794803
Type PatternTypeRequest::evaluate(Evaluator &evaluator,
795804
ContextualPattern pattern) const {
796805
Pattern *P = pattern.getPattern();
@@ -1300,7 +1309,7 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
13001309
auto *BaseTE = TypeExpr::createImplicit(type, Context);
13011310
P = new (Context) EnumElementPattern(
13021311
BaseTE, NLE->getLoc(), DeclNameLoc(NLE->getLoc()),
1303-
NoneEnumElement->createNameRef(), NoneEnumElement, nullptr);
1312+
NoneEnumElement->createNameRef(), NoneEnumElement, nullptr, dc);
13041313
return TypeChecker::coercePatternToType(
13051314
pattern.forSubPattern(P, /*retainTopLevel=*/true), type, options);
13061315
} else {
@@ -1355,7 +1364,7 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
13551364
auto *base = TypeExpr::createImplicit(extraOptTy, Context);
13561365
sub = new (Context) EnumElementPattern(
13571366
base, IP->getStartLoc(), DeclNameLoc(IP->getEndLoc()),
1358-
some->createNameRef(), nullptr, sub);
1367+
some->createNameRef(), nullptr, sub, dc);
13591368
sub->setImplicit();
13601369
}
13611370

0 commit comments

Comments
 (0)