Skip to content

Commit e296735

Browse files
authored
Merge pull request #74587 from hamishknight/pattern-resolution-6.0
[6.0] [Sema] Requestify pattern resolution
2 parents 2eb61de + 0060c1a commit e296735

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)