Skip to content

Commit 26e8245

Browse files
committed
[Sema] Requestify pattern resolution
Add a cached request to perform pattern resolution. This is needed to prevent the constraint system from resolving the same pattern multiple times along different solver paths, which could result in creating different pattern nodes for each path. Once pattern resolution is moved to pre-checking we ought to be able to make this uncached. rdar://128661960
1 parent de9aefc commit 26e8245

File tree

5 files changed

+52
-9
lines changed

5 files changed

+52
-9
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2527,6 +2527,33 @@ class EnumElementExprPatternRequest
25272527
bool isCached() const { return true; }
25282528
};
25292529

2530+
/// Perform top-down syntactic disambiguation of a pattern. Where ambiguous
2531+
/// expr/pattern productions occur (tuples, function calls, etc.), favor the
2532+
/// pattern interpretation if it forms a valid pattern; otherwise, leave it as
2533+
/// an expression. This does no type-checking except for the bare minimum to
2534+
/// disambiguate semantics-dependent pattern forms.
2535+
///
2536+
/// Currently cached to ensure the constraint system does not resolve the same
2537+
/// pattern multiple times along different solver paths. Once we move pattern
2538+
/// resolution into pre-checking, we could make this uncached.
2539+
class ResolvePatternRequest
2540+
: public SimpleRequest<ResolvePatternRequest,
2541+
Pattern *(Pattern *, DeclContext *, bool),
2542+
RequestFlags::Cached> {
2543+
public:
2544+
using SimpleRequest::SimpleRequest;
2545+
2546+
private:
2547+
friend SimpleRequest;
2548+
2549+
// Evaluation.
2550+
Pattern *evaluate(Evaluator &evaluator, Pattern *P, DeclContext *DC,
2551+
bool isStmtCondition) const;
2552+
public:
2553+
// Cached.
2554+
bool isCached() const { return true; }
2555+
};
2556+
25302557
class InterfaceTypeRequest :
25312558
public SimpleRequest<InterfaceTypeRequest,
25322559
Type (ValueDecl *),

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ SWIFT_REQUEST(TypeChecker, ExprPatternMatchRequest,
248248
SWIFT_REQUEST(TypeChecker, EnumElementExprPatternRequest,
249249
ExprPattern *(const EnumElementPattern *),
250250
Cached, NoLocationInfo)
251+
SWIFT_REQUEST(TypeChecker, ResolvePatternRequest,
252+
Pattern *(Pattern *, DeclContext *, bool),
253+
Cached, NoLocationInfo)
251254
SWIFT_REQUEST(TypeChecker, OpaqueReadOwnershipRequest,
252255
OpaqueReadOwnership(AbstractStorageDecl *), SeparatelyCached,
253256
NoLocationInfo)

lib/Sema/TypeCheckPattern.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -624,13 +624,9 @@ class ResolvePattern : public ASTVisitor<ResolvePattern,
624624

625625
} // end anonymous namespace
626626

627-
/// Perform top-down syntactic disambiguation of a pattern. Where ambiguous
628-
/// expr/pattern productions occur (tuples, function calls, etc.), favor the
629-
/// pattern interpretation if it forms a valid pattern; otherwise, leave it as
630-
/// an expression. This does no type-checking except for the bare minimum to
631-
/// disambiguate semantics-dependent pattern forms.
632-
Pattern *TypeChecker::resolvePattern(Pattern *P, DeclContext *DC,
633-
bool isStmtCondition) {
627+
Pattern *ResolvePatternRequest::evaluate(Evaluator &evaluator, Pattern *P,
628+
DeclContext *DC,
629+
bool isStmtCondition) const {
634630
P = ResolvePattern(DC).visit(P);
635631

636632
TypeChecker::diagnoseDuplicateBoundVars(P);
@@ -691,6 +687,13 @@ Pattern *TypeChecker::resolvePattern(Pattern *P, DeclContext *DC,
691687
return P;
692688
}
693689

690+
Pattern *TypeChecker::resolvePattern(Pattern *P, DeclContext *DC,
691+
bool isStmtCondition) {
692+
auto &eval = DC->getASTContext().evaluator;
693+
return evaluateOrDefault(eval, ResolvePatternRequest{P, DC, isStmtCondition},
694+
nullptr);
695+
}
696+
694697
static Type
695698
validateTypedPattern(TypedPattern *TP, DeclContext *dc,
696699
TypeResolutionOptions options,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %batch-code-completion
2+
3+
func takeClosure(closure: () -> Bool) {}
4+
5+
func test(someLocal: Int) {
6+
takeClosure {
7+
if case .begin(#^COMPLETE^#)
8+
}
9+
}
10+
// COMPLETE: someLocal

validation-test/Sema/type_checker_crashers_fixed/rdar92327807.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ func test(result: MyEnum, optResult: MyEnum?) {
1818
}
1919

2020
let _ = {
21-
if let .co = result { // expected-error 2 {{pattern matching in a condition requires the 'case' keyword}}
21+
if let .co = result { // expected-error {{pattern matching in a condition requires the 'case' keyword}}
2222
// expected-error@-1 {{type 'MyEnum' has no member 'co'}}
2323
}
2424
}
2525

2626
let _ = {
27-
if let .co = optResult { // expected-error 2 {{pattern matching in a condition requires the 'case' keyword}}
27+
if let .co = optResult { // expected-error {{pattern matching in a condition requires the 'case' keyword}}
2828
// expected-error@-1 {{type 'MyEnum?' has no member 'co'}}
2929
}
3030
}

0 commit comments

Comments
 (0)