Skip to content

[Sema] Some NFC pattern changes #63996

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions include/swift/AST/Pattern.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,6 @@ class OptionalSomePattern : public Pattern {
}
};


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

/// An implicit variable used to represent the RHS value of the match.
VarDecl *MatchVar;
VarDecl *MatchVar = nullptr;

ExprPattern(Expr *E, bool isResolved)
: Pattern(PatternKind::Expr), SubExprAndIsResolved(E, isResolved) {}

public:
/// Construct an ExprPattern.
ExprPattern(Expr *e, bool isResolved, Expr *matchExpr, VarDecl *matchVar);

/// Construct an unresolved ExprPattern.
ExprPattern(Expr *e)
: ExprPattern(e, false, nullptr, nullptr)
{}

/// Construct a resolved ExprPattern.
ExprPattern(Expr *e, Expr *matchExpr, VarDecl *matchVar)
: ExprPattern(e, true, matchExpr, matchVar)
{}
/// Create a new parsed unresolved ExprPattern.
static ExprPattern *createParsed(ASTContext &ctx, Expr *E);

/// Create a new resolved ExprPattern. This should be used in cases
/// where a user-written expression should be treated as an ExprPattern.
static ExprPattern *createResolved(ASTContext &ctx, Expr *E);

/// Create a new implicit resolved ExprPattern.
static ExprPattern *createImplicit(ASTContext &ctx, Expr *E);

Expr *getSubExpr() const { return SubExprAndIsResolved.getPointer(); }
void setSubExpr(Expr *e) { SubExprAndIsResolved.setPointer(e); }
Expand Down
31 changes: 15 additions & 16 deletions include/swift/Sema/ConstraintSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -2347,13 +2347,18 @@ class SolutionApplicationTarget {
expression.convertType = type;
}

/// Whether this target is for an initialization expression and pattern.
bool isForInitialization() const {
return kind == Kind::expression &&
expression.contextualPurpose == CTP_Initialization;
}

/// For a pattern initialization target, retrieve the pattern.
Pattern *getInitializationPattern() const {
if (kind == Kind::uninitializedVar)
return uninitializedVar.declaration.get<Pattern *>();

assert(kind == Kind::expression);
assert(expression.contextualPurpose == CTP_Initialization);
assert(isForInitialization());
return expression.pattern;
}

Expand All @@ -2378,16 +2383,14 @@ class SolutionApplicationTarget {

/// Whether this is an initialization for an Optional.Some pattern.
bool isOptionalSomePatternInit() const {
return kind == Kind::expression &&
expression.contextualPurpose == CTP_Initialization &&
dyn_cast_or_null<OptionalSomePattern>(expression.pattern) &&
!expression.pattern->isImplicit();
return isForInitialization() &&
dyn_cast_or_null<OptionalSomePattern>(expression.pattern) &&
!expression.pattern->isImplicit();
}

/// Check whether this is an initialization for `async let` pattern.
bool isAsyncLetInitializer() const {
if (!(kind == Kind::expression &&
expression.contextualPurpose == CTP_Initialization))
if (!isForInitialization())
return false;

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

auto *wrappedVar = expression.propertyWrapper.wrappedVar;
Expand All @@ -2439,20 +2441,17 @@ class SolutionApplicationTarget {
/// Retrieve the wrapped variable when initializing a pattern with a
/// property wrapper.
VarDecl *getInitializationWrappedVar() const {
assert(kind == Kind::expression);
assert(expression.contextualPurpose == CTP_Initialization);
assert(isForInitialization());
return expression.propertyWrapper.wrappedVar;
}

PatternBindingDecl *getInitializationPatternBindingDecl() const {
assert(kind == Kind::expression);
assert(expression.contextualPurpose == CTP_Initialization);
assert(isForInitialization());
return expression.initialization.patternBinding;
}

unsigned getInitializationPatternBindingIndex() const {
assert(kind == Kind::expression);
assert(expression.contextualPurpose == CTP_Initialization);
assert(isForInitialization());
return expression.initialization.patternBindingIndex;
}

Expand Down
18 changes: 12 additions & 6 deletions lib/AST/Pattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,12 +501,18 @@ void IsPattern::setCastType(Type type) {

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

/// Construct an ExprPattern.
ExprPattern::ExprPattern(Expr *e, bool isResolved, Expr *matchExpr,
VarDecl *matchVar)
: Pattern(PatternKind::Expr), SubExprAndIsResolved(e, isResolved),
MatchExpr(matchExpr), MatchVar(matchVar) {
assert(!matchExpr || e->isImplicit() == matchExpr->isImplicit());
ExprPattern *ExprPattern::createParsed(ASTContext &ctx, Expr *E) {
return new (ctx) ExprPattern(E, /*isResolved*/ false);
}

ExprPattern *ExprPattern::createResolved(ASTContext &ctx, Expr *E) {
return new (ctx) ExprPattern(E, /*isResolved*/ true);
}

ExprPattern *ExprPattern::createImplicit(ASTContext &ctx, Expr *E) {
auto *EP = ExprPattern::createResolved(ctx, E);
EP->setImplicit();
return EP;
}

SourceLoc EnumElementPattern::getStartLoc() const {
Expand Down
5 changes: 3 additions & 2 deletions lib/Parse/ParsePattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1314,8 +1314,9 @@ ParserResult<Pattern> Parser::parseMatchingPattern(bool isExprBasic) {
// UnresolvedPatternExpr. Transform this now to simplify later code.
if (auto *UPE = dyn_cast<UnresolvedPatternExpr>(subExpr.get()))
return makeParserResult(status, UPE->getSubPattern());

return makeParserResult(status, new (Context) ExprPattern(subExpr.get()));

auto *EP = ExprPattern::createParsed(Context, subExpr.get());
return makeParserResult(status, EP);
}

ParserResult<Pattern> Parser::parseMatchingPatternAsLetOrVar(bool isLet,
Expand Down
2 changes: 1 addition & 1 deletion lib/Parse/ParseStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,7 @@ static void parseGuardedPattern(Parser &P, GuardedPattern &result,
// Do some special-case code completion for the start of the pattern.
if (P.Tok.is(tok::code_complete)) {
auto CCE = new (P.Context) CodeCompletionExpr(P.Tok.getLoc());
result.ThePattern = new (P.Context) ExprPattern(CCE);
result.ThePattern = ExprPattern::createParsed(P.Context, CCE);
if (P.IDECallbacks) {
switch (parsingContext) {
case GuardedPatternContext::Case:
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/CSGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4577,7 +4577,7 @@ bool ConstraintSystem::generateConstraints(
}

// For an initialization target, generate constraints for the pattern.
if (target.getExprContextualTypePurpose() == CTP_Initialization &&
if (target.isForInitialization() &&
generateInitPatternConstraints(*this, target, expr)) {
return true;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9847,8 +9847,8 @@ static bool inferEnumMemberThroughTildeEqualsOperator(

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

auto tildeEqualsApplication =
TypeChecker::synthesizeTildeEqualsOperatorApplication(EP, DC, enumTy);
Expand Down
4 changes: 1 addition & 3 deletions lib/Sema/DerivedConformanceCodingKey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,7 @@ deriveBodyCodingKey_init_stringValue(AbstractFunctionDecl *initDecl, void *) {
for (auto *elt : elements) {
auto *litExpr = new (C) StringLiteralExpr(elt->getNameStr(), SourceRange(),
/*Implicit=*/true);
auto *litPat = new (C) ExprPattern(litExpr, /*IsResolved=*/true, nullptr,
nullptr);
litPat->setImplicit();
auto *litPat = ExprPattern::createImplicit(C, litExpr);

auto labelItem = CaseLabelItem(litPat);

Expand Down
4 changes: 1 addition & 3 deletions lib/Sema/DerivedConformanceRawRepresentable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,7 @@ deriveBodyRawRepresentable_init(AbstractFunctionDecl *initDecl, void *) {
stringExprs.push_back(litExpr);
litExpr = IntegerLiteralExpr::createFromUnsigned(C, Idx, SourceLoc());
}
auto litPat = new (C) ExprPattern(litExpr, /*isResolved*/ true,
nullptr, nullptr);
litPat->setImplicit();
auto *litPat = ExprPattern::createImplicit(C, litExpr);

/// Statements in the body of this case.
SmallVector<ASTNode, 2> stmts;
Expand Down
39 changes: 3 additions & 36 deletions lib/Sema/TypeCheckPattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,39 +225,7 @@ struct ExprToDeclRefTypeRepr : public ASTVisitor<ExprToDeclRefTypeRepr, bool> {
};
} // end anonymous namespace


namespace {
class UnresolvedPatternFinder : public ASTWalker {
bool &HadUnresolvedPattern;
public:

UnresolvedPatternFinder(bool &HadUnresolvedPattern)
: HadUnresolvedPattern(HadUnresolvedPattern) {}

MacroWalking getMacroWalkingBehavior() const override {
return MacroWalking::Arguments;
}

PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
// If we find an UnresolvedPatternExpr, return true.
if (isa<UnresolvedPatternExpr>(E)) {
HadUnresolvedPattern = true;
return Action::SkipChildren(E);
}

return Action::Continue(E);
}

static bool hasAny(Expr *E) {
bool HasUnresolvedPattern = false;
E->walk(UnresolvedPatternFinder(HasUnresolvedPattern));
return HasUnresolvedPattern;
}
};
} // end anonymous namespace

namespace {

class ResolvePattern : public ASTVisitor<ResolvePattern,
/*ExprRetTy=*/Pattern*,
/*StmtRetTy=*/void,
Expand All @@ -276,7 +244,7 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
if (Pattern *p = visit(E))
return p;

return new (Context) ExprPattern(E, nullptr, nullptr);
return ExprPattern::createResolved(Context, E);
}

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

} // end anonymous namespace


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