Skip to content

Commit f6f5e89

Browse files
authored
Merge pull request #63996 from hamishknight/nfc-pattern-changes
2 parents 2d0b78a + 9b8bc60 commit f6f5e89

File tree

10 files changed

+53
-85
lines changed

10 files changed

+53
-85
lines changed

include/swift/AST/Pattern.h

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,6 @@ class OptionalSomePattern : public Pattern {
639639
}
640640
};
641641

642-
643642
/// A pattern which matches a value obtained by evaluating an expression.
644643
/// The match will be tested using user-defined '~=' operator function lookup;
645644
/// the match succeeds if 'patternValue ~= matchedValue' produces a true value.
@@ -649,24 +648,24 @@ class ExprPattern : public Pattern {
649648
/// An expression constructed during type-checking that produces a call to the
650649
/// '~=' operator comparing the match expression on the left to the matched
651650
/// value on the right.
652-
Expr *MatchExpr;
651+
Expr *MatchExpr = nullptr;
653652

654653
/// An implicit variable used to represent the RHS value of the match.
655-
VarDecl *MatchVar;
654+
VarDecl *MatchVar = nullptr;
655+
656+
ExprPattern(Expr *E, bool isResolved)
657+
: Pattern(PatternKind::Expr), SubExprAndIsResolved(E, isResolved) {}
656658

657659
public:
658-
/// Construct an ExprPattern.
659-
ExprPattern(Expr *e, bool isResolved, Expr *matchExpr, VarDecl *matchVar);
660-
661-
/// Construct an unresolved ExprPattern.
662-
ExprPattern(Expr *e)
663-
: ExprPattern(e, false, nullptr, nullptr)
664-
{}
665-
666-
/// Construct a resolved ExprPattern.
667-
ExprPattern(Expr *e, Expr *matchExpr, VarDecl *matchVar)
668-
: ExprPattern(e, true, matchExpr, matchVar)
669-
{}
660+
/// Create a new parsed unresolved ExprPattern.
661+
static ExprPattern *createParsed(ASTContext &ctx, Expr *E);
662+
663+
/// Create a new resolved ExprPattern. This should be used in cases
664+
/// where a user-written expression should be treated as an ExprPattern.
665+
static ExprPattern *createResolved(ASTContext &ctx, Expr *E);
666+
667+
/// Create a new implicit resolved ExprPattern.
668+
static ExprPattern *createImplicit(ASTContext &ctx, Expr *E);
670669

671670
Expr *getSubExpr() const { return SubExprAndIsResolved.getPointer(); }
672671
void setSubExpr(Expr *e) { SubExprAndIsResolved.setPointer(e); }

include/swift/Sema/ConstraintSystem.h

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2347,13 +2347,18 @@ class SolutionApplicationTarget {
23472347
expression.convertType = type;
23482348
}
23492349

2350+
/// Whether this target is for an initialization expression and pattern.
2351+
bool isForInitialization() const {
2352+
return kind == Kind::expression &&
2353+
expression.contextualPurpose == CTP_Initialization;
2354+
}
2355+
23502356
/// For a pattern initialization target, retrieve the pattern.
23512357
Pattern *getInitializationPattern() const {
23522358
if (kind == Kind::uninitializedVar)
23532359
return uninitializedVar.declaration.get<Pattern *>();
23542360

2355-
assert(kind == Kind::expression);
2356-
assert(expression.contextualPurpose == CTP_Initialization);
2361+
assert(isForInitialization());
23572362
return expression.pattern;
23582363
}
23592364

@@ -2378,16 +2383,14 @@ class SolutionApplicationTarget {
23782383

23792384
/// Whether this is an initialization for an Optional.Some pattern.
23802385
bool isOptionalSomePatternInit() const {
2381-
return kind == Kind::expression &&
2382-
expression.contextualPurpose == CTP_Initialization &&
2383-
dyn_cast_or_null<OptionalSomePattern>(expression.pattern) &&
2384-
!expression.pattern->isImplicit();
2386+
return isForInitialization() &&
2387+
dyn_cast_or_null<OptionalSomePattern>(expression.pattern) &&
2388+
!expression.pattern->isImplicit();
23852389
}
23862390

23872391
/// Check whether this is an initialization for `async let` pattern.
23882392
bool isAsyncLetInitializer() const {
2389-
if (!(kind == Kind::expression &&
2390-
expression.contextualPurpose == CTP_Initialization))
2393+
if (!isForInitialization())
23912394
return false;
23922395

23932396
if (auto *PBD = getInitializationPatternBindingDecl())
@@ -2411,8 +2414,7 @@ class SolutionApplicationTarget {
24112414
/// first \c wrappedValue argument of an apply expression so the initializer
24122415
/// expression can be turned into a property wrapper generator function.
24132416
bool shouldInjectWrappedValuePlaceholder(ApplyExpr *apply) const {
2414-
if (kind != Kind::expression ||
2415-
expression.contextualPurpose != CTP_Initialization)
2417+
if (!isForInitialization())
24162418
return false;
24172419

24182420
auto *wrappedVar = expression.propertyWrapper.wrappedVar;
@@ -2439,20 +2441,17 @@ class SolutionApplicationTarget {
24392441
/// Retrieve the wrapped variable when initializing a pattern with a
24402442
/// property wrapper.
24412443
VarDecl *getInitializationWrappedVar() const {
2442-
assert(kind == Kind::expression);
2443-
assert(expression.contextualPurpose == CTP_Initialization);
2444+
assert(isForInitialization());
24442445
return expression.propertyWrapper.wrappedVar;
24452446
}
24462447

24472448
PatternBindingDecl *getInitializationPatternBindingDecl() const {
2448-
assert(kind == Kind::expression);
2449-
assert(expression.contextualPurpose == CTP_Initialization);
2449+
assert(isForInitialization());
24502450
return expression.initialization.patternBinding;
24512451
}
24522452

24532453
unsigned getInitializationPatternBindingIndex() const {
2454-
assert(kind == Kind::expression);
2455-
assert(expression.contextualPurpose == CTP_Initialization);
2454+
assert(isForInitialization());
24562455
return expression.initialization.patternBindingIndex;
24572456
}
24582457

lib/AST/Pattern.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -501,12 +501,18 @@ void IsPattern::setCastType(Type type) {
501501

502502
TypeRepr *IsPattern::getCastTypeRepr() const { return CastType->getTypeRepr(); }
503503

504-
/// Construct an ExprPattern.
505-
ExprPattern::ExprPattern(Expr *e, bool isResolved, Expr *matchExpr,
506-
VarDecl *matchVar)
507-
: Pattern(PatternKind::Expr), SubExprAndIsResolved(e, isResolved),
508-
MatchExpr(matchExpr), MatchVar(matchVar) {
509-
assert(!matchExpr || e->isImplicit() == matchExpr->isImplicit());
504+
ExprPattern *ExprPattern::createParsed(ASTContext &ctx, Expr *E) {
505+
return new (ctx) ExprPattern(E, /*isResolved*/ false);
506+
}
507+
508+
ExprPattern *ExprPattern::createResolved(ASTContext &ctx, Expr *E) {
509+
return new (ctx) ExprPattern(E, /*isResolved*/ true);
510+
}
511+
512+
ExprPattern *ExprPattern::createImplicit(ASTContext &ctx, Expr *E) {
513+
auto *EP = ExprPattern::createResolved(ctx, E);
514+
EP->setImplicit();
515+
return EP;
510516
}
511517

512518
SourceLoc EnumElementPattern::getStartLoc() const {

lib/Parse/ParsePattern.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,8 +1314,9 @@ ParserResult<Pattern> Parser::parseMatchingPattern(bool isExprBasic) {
13141314
// UnresolvedPatternExpr. Transform this now to simplify later code.
13151315
if (auto *UPE = dyn_cast<UnresolvedPatternExpr>(subExpr.get()))
13161316
return makeParserResult(status, UPE->getSubPattern());
1317-
1318-
return makeParserResult(status, new (Context) ExprPattern(subExpr.get()));
1317+
1318+
auto *EP = ExprPattern::createParsed(Context, subExpr.get());
1319+
return makeParserResult(status, EP);
13191320
}
13201321

13211322
ParserResult<Pattern> Parser::parseMatchingPatternAsLetOrVar(bool isLet,

lib/Parse/ParseStmt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@ static void parseGuardedPattern(Parser &P, GuardedPattern &result,
10951095
// Do some special-case code completion for the start of the pattern.
10961096
if (P.Tok.is(tok::code_complete)) {
10971097
auto CCE = new (P.Context) CodeCompletionExpr(P.Tok.getLoc());
1098-
result.ThePattern = new (P.Context) ExprPattern(CCE);
1098+
result.ThePattern = ExprPattern::createParsed(P.Context, CCE);
10991099
if (P.IDECallbacks) {
11001100
switch (parsingContext) {
11011101
case GuardedPatternContext::Case:

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4577,7 +4577,7 @@ bool ConstraintSystem::generateConstraints(
45774577
}
45784578

45794579
// For an initialization target, generate constraints for the pattern.
4580-
if (target.getExprContextualTypePurpose() == CTP_Initialization &&
4580+
if (target.isForInitialization() &&
45814581
generateInitPatternConstraints(*this, target, expr)) {
45824582
return true;
45834583
}

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9847,8 +9847,8 @@ static bool inferEnumMemberThroughTildeEqualsOperator(
98479847

98489848
// Slots for expression and variable are going to be filled via
98499849
// synthesizing ~= operator application.
9850-
auto *EP = new (ctx) ExprPattern(pattern->getUnresolvedOriginalExpr(),
9851-
/*matchExpr=*/nullptr, /*matchVar=*/nullptr);
9850+
auto *EP =
9851+
ExprPattern::createResolved(ctx, pattern->getUnresolvedOriginalExpr());
98529852

98539853
auto tildeEqualsApplication =
98549854
TypeChecker::synthesizeTildeEqualsOperatorApplication(EP, DC, enumTy);

lib/Sema/DerivedConformanceCodingKey.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,7 @@ deriveBodyCodingKey_init_stringValue(AbstractFunctionDecl *initDecl, void *) {
277277
for (auto *elt : elements) {
278278
auto *litExpr = new (C) StringLiteralExpr(elt->getNameStr(), SourceRange(),
279279
/*Implicit=*/true);
280-
auto *litPat = new (C) ExprPattern(litExpr, /*IsResolved=*/true, nullptr,
281-
nullptr);
282-
litPat->setImplicit();
280+
auto *litPat = ExprPattern::createImplicit(C, litExpr);
283281

284282
auto labelItem = CaseLabelItem(litPat);
285283

lib/Sema/DerivedConformanceRawRepresentable.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,7 @@ deriveBodyRawRepresentable_init(AbstractFunctionDecl *initDecl, void *) {
323323
stringExprs.push_back(litExpr);
324324
litExpr = IntegerLiteralExpr::createFromUnsigned(C, Idx, SourceLoc());
325325
}
326-
auto litPat = new (C) ExprPattern(litExpr, /*isResolved*/ true,
327-
nullptr, nullptr);
328-
litPat->setImplicit();
326+
auto *litPat = ExprPattern::createImplicit(C, litExpr);
329327

330328
/// Statements in the body of this case.
331329
SmallVector<ASTNode, 2> stmts;

lib/Sema/TypeCheckPattern.cpp

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -225,39 +225,7 @@ struct ExprToDeclRefTypeRepr : public ASTVisitor<ExprToDeclRefTypeRepr, bool> {
225225
};
226226
} // end anonymous namespace
227227

228-
229-
namespace {
230-
class UnresolvedPatternFinder : public ASTWalker {
231-
bool &HadUnresolvedPattern;
232-
public:
233-
234-
UnresolvedPatternFinder(bool &HadUnresolvedPattern)
235-
: HadUnresolvedPattern(HadUnresolvedPattern) {}
236-
237-
MacroWalking getMacroWalkingBehavior() const override {
238-
return MacroWalking::Arguments;
239-
}
240-
241-
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
242-
// If we find an UnresolvedPatternExpr, return true.
243-
if (isa<UnresolvedPatternExpr>(E)) {
244-
HadUnresolvedPattern = true;
245-
return Action::SkipChildren(E);
246-
}
247-
248-
return Action::Continue(E);
249-
}
250-
251-
static bool hasAny(Expr *E) {
252-
bool HasUnresolvedPattern = false;
253-
E->walk(UnresolvedPatternFinder(HasUnresolvedPattern));
254-
return HasUnresolvedPattern;
255-
}
256-
};
257-
} // end anonymous namespace
258-
259228
namespace {
260-
261229
class ResolvePattern : public ASTVisitor<ResolvePattern,
262230
/*ExprRetTy=*/Pattern*,
263231
/*StmtRetTy=*/void,
@@ -276,7 +244,7 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
276244
if (Pattern *p = visit(E))
277245
return p;
278246

279-
return new (Context) ExprPattern(E, nullptr, nullptr);
247+
return ExprPattern::createResolved(Context, E);
280248
}
281249

282250
/// Turn an argument list into a matching tuple or paren pattern.
@@ -652,7 +620,6 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
652620

653621
} // end anonymous namespace
654622

655-
656623
/// Perform top-down syntactic disambiguation of a pattern. Where ambiguous
657624
/// expr/pattern productions occur (tuples, function calls, etc.), favor the
658625
/// pattern interpretation if it forms a valid pattern; otherwise, leave it as
@@ -1460,8 +1427,8 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern,
14601427
// If we have the original expression parse tree, try reinterpreting
14611428
// it as an expr-pattern if enum element lookup failed, since `.foo`
14621429
// could also refer to a static member of the context type.
1463-
P = new (Context) ExprPattern(EEP->getUnresolvedOriginalExpr(),
1464-
nullptr, nullptr);
1430+
P = ExprPattern::createResolved(Context,
1431+
EEP->getUnresolvedOriginalExpr());
14651432
return coercePatternToType(
14661433
pattern.forSubPattern(P, /*retainTopLevel=*/true), type,
14671434
options);

0 commit comments

Comments
 (0)