From f5c0c9cb352b3780b62a5a95f3b39bdbb6588adf Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Wed, 4 May 2022 16:08:48 +0200 Subject: [PATCH] [CodeCompletion] Maintain LeaveClosureBodiesUnchecked when checking pattern binding Before, we were dropping `LeaveClosureBodiesUnchecked` when checking a pattern binding request which caused missing completions inside variables initialized by closures. rdar://92603748 [#58610] --- include/swift/AST/TypeCheckRequests.h | 7 ++++--- include/swift/AST/TypeCheckerTypeIDZone.def | 2 +- lib/AST/Decl.cpp | 3 ++- lib/Sema/TypeCheckDecl.cpp | 3 ++- lib/Sema/TypeCheckDeclPrimary.cpp | 4 +++- lib/Sema/TypeCheckStorage.cpp | 15 +++++++++------ test/IDE/complete_in_closures.swift | 20 ++++++++++++++++++++ 7 files changed, 41 insertions(+), 13 deletions(-) diff --git a/include/swift/AST/TypeCheckRequests.h b/include/swift/AST/TypeCheckRequests.h index e16fca21e812a..6c190a1f7de27 100644 --- a/include/swift/AST/TypeCheckRequests.h +++ b/include/swift/AST/TypeCheckRequests.h @@ -2264,7 +2264,7 @@ class ResultTypeRequest class PatternBindingEntryRequest : public SimpleRequest { public: using SimpleRequest::SimpleRequest; @@ -2273,8 +2273,9 @@ class PatternBindingEntryRequest friend SimpleRequest; // Evaluation. - const PatternBindingEntry * - evaluate(Evaluator &evaluator, PatternBindingDecl *PBD, unsigned i) const; + const PatternBindingEntry *evaluate(Evaluator &evaluator, + PatternBindingDecl *PBD, unsigned i, + bool LeaveClosureBodiesUnchecked) const; public: // Separate caching. diff --git a/include/swift/AST/TypeCheckerTypeIDZone.def b/include/swift/AST/TypeCheckerTypeIDZone.def index 4ba53580348ed..8f68235763fef 100644 --- a/include/swift/AST/TypeCheckerTypeIDZone.def +++ b/include/swift/AST/TypeCheckerTypeIDZone.def @@ -266,7 +266,7 @@ SWIFT_REQUEST(TypeChecker, OverriddenDeclsRequest, llvm::TinyPtrVector(ValueDecl *), SeparatelyCached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, PatternBindingEntryRequest, - const PatternBindingEntry *(PatternBindingDecl *, unsigned), + const PatternBindingEntry *(PatternBindingDecl *, unsigned, bool), SeparatelyCached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, PrimarySourceFilesRequest, ArrayRef(ModuleDecl *), Cached, NoLocationInfo) diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 81cd76ae1b5dc..bb2ee235aaeb3 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1969,7 +1969,8 @@ bool PatternBindingDecl::isComputingPatternBindingEntry( const VarDecl *vd) const { unsigned i = getPatternEntryIndexForVarDecl(vd); return getASTContext().evaluator.hasActiveRequest( - PatternBindingEntryRequest{const_cast(this), i}); + PatternBindingEntryRequest{const_cast(this), i, + /*LeaveClosureBodyUnchecked=*/false}); } bool PatternBindingDecl::isExplicitlyInitialized(unsigned i) const { diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index be0c8eb3835b0..99df7261b1b9a 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -2453,7 +2453,8 @@ NamingPatternRequest::evaluate(Evaluator &evaluator, VarDecl *VD) const { // and TypeCheckPattern handle the others. But that's all really gross. unsigned i = PBD->getPatternEntryIndexForVarDecl(VD); (void)evaluateOrDefault(evaluator, - PatternBindingEntryRequest{PBD, i}, + PatternBindingEntryRequest{ + PBD, i, /*LeaveClosureBodiesUnchecked=*/false}, nullptr); if (PBD->isInvalid()) { VD->getParentPattern()->setType(ErrorType::get(Context)); diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index fbf9593ef7b66..07f60a1b3ef6f 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -2023,7 +2023,9 @@ class DeclChecker : public DeclVisitor { PBD->isFullyValidated(i) ? &PBD->getPatternList()[i] : evaluateOrDefault(Ctx.evaluator, - PatternBindingEntryRequest{PBD, i}, nullptr); + PatternBindingEntryRequest{ + PBD, i, LeaveClosureBodiesUnchecked}, + nullptr); assert(entry && "No pattern binding entry?"); const auto *Pat = PBD->getPattern(i); diff --git a/lib/Sema/TypeCheckStorage.cpp b/lib/Sema/TypeCheckStorage.cpp index 09efa733b3d64..a726f994bb171 100644 --- a/lib/Sema/TypeCheckStorage.cpp +++ b/lib/Sema/TypeCheckStorage.cpp @@ -250,10 +250,9 @@ StoredPropertiesAndMissingMembersRequest::evaluate(Evaluator &evaluator, } /// Validate the \c entryNumber'th entry in \c binding. -const PatternBindingEntry * -PatternBindingEntryRequest::evaluate(Evaluator &eval, - PatternBindingDecl *binding, - unsigned entryNumber) const { +const PatternBindingEntry *PatternBindingEntryRequest::evaluate( + Evaluator &eval, PatternBindingDecl *binding, unsigned entryNumber, + bool LeaveClosureBodiesUnchecked) const { const auto &pbe = binding->getPatternList()[entryNumber]; auto &Context = binding->getASTContext(); @@ -363,8 +362,12 @@ PatternBindingEntryRequest::evaluate(Evaluator &eval, if (patternType->hasUnresolvedType() || patternType->hasPlaceholder() || patternType->hasUnboundGenericType()) { - if (TypeChecker::typeCheckPatternBinding(binding, entryNumber, - patternType)) { + TypeCheckExprOptions options; + if (LeaveClosureBodiesUnchecked) { + options |= TypeCheckExprFlags::LeaveClosureBodyUnchecked; + } + if (TypeChecker::typeCheckPatternBinding(binding, entryNumber, patternType, + options)) { binding->setInvalid(); return &pbe; } diff --git a/test/IDE/complete_in_closures.swift b/test/IDE/complete_in_closures.swift index cb1d7a56f0a93..850af60f5da03 100644 --- a/test/IDE/complete_in_closures.swift +++ b/test/IDE/complete_in_closures.swift @@ -396,3 +396,23 @@ func testSignature() { // NOTE: For effects specifiers completion (e.g. '() -> Void') see test/IDE/complete_concurrency_specifier.swift } + +func testClosureInPatternBindingInit() { + enum DragState { + case dragging(translation: Int, predictedLocation: Int) + } + + func pnChanged(_ action: () -> Void) {} + + func foo() { + var gestureViewState: DragState = .dragging(translation: 0, predictedLocation: 0) + let longPressDrag = pnChanged { + _ = 1 + gestureViewState = .dragging(translation: 0, #^CLOSURE_IN_PATTERN_BINDING^#predictedLocation: 0) + } + } + // CLOSURE_IN_PATTERN_BINDING: Begin completions, 1 items + // CLOSURE_IN_PATTERN_BINDING-DAG: Pattern/Local/Flair[ArgLabels]: {#predictedLocation: Int#}[#Int#]; + // CLOSURE_IN_PATTERN_BINDING: End completion + +}