Skip to content

Commit db48ace

Browse files
committed
[CodeCompletion] Let FindLocalVal walk into ExprPattern
Some conditions in control flow statements are parsed as expression patterns, then resolved to "pattern"s later in Sema. In code completion, they might not be type checked at all. Previously, when collecting visible declarations for completion candidates, it didn't walk into `ExprPattern`, and thus it didn't find the variables inside. Use standard `Pattern::forEachVariable()` that looks into `ExprPattern` instead of using its custom recursive logic. rdar://86050684
1 parent 7dc36c3 commit db48ace

File tree

2 files changed

+21
-34
lines changed

2 files changed

+21
-34
lines changed

lib/AST/NameLookup.cpp

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2778,40 +2778,7 @@ swift::getDirectlyInheritedNominalTypeDecls(
27782778
}
27792779

27802780
void FindLocalVal::checkPattern(const Pattern *Pat, DeclVisibilityKind Reason) {
2781-
switch (Pat->getKind()) {
2782-
case PatternKind::Tuple:
2783-
for (auto &field : cast<TuplePattern>(Pat)->getElements())
2784-
checkPattern(field.getPattern(), Reason);
2785-
return;
2786-
case PatternKind::Paren:
2787-
case PatternKind::Typed:
2788-
case PatternKind::Binding:
2789-
return checkPattern(Pat->getSemanticsProvidingPattern(), Reason);
2790-
case PatternKind::Named:
2791-
return checkValueDecl(cast<NamedPattern>(Pat)->getDecl(), Reason);
2792-
case PatternKind::EnumElement: {
2793-
auto *OP = cast<EnumElementPattern>(Pat);
2794-
if (OP->hasSubPattern())
2795-
checkPattern(OP->getSubPattern(), Reason);
2796-
return;
2797-
}
2798-
case PatternKind::OptionalSome:
2799-
checkPattern(cast<OptionalSomePattern>(Pat)->getSubPattern(), Reason);
2800-
return;
2801-
2802-
case PatternKind::Is: {
2803-
auto *isPat = cast<IsPattern>(Pat);
2804-
if (isPat->hasSubPattern())
2805-
checkPattern(isPat->getSubPattern(), Reason);
2806-
return;
2807-
}
2808-
2809-
// Handle non-vars.
2810-
case PatternKind::Bool:
2811-
case PatternKind::Expr:
2812-
case PatternKind::Any:
2813-
return;
2814-
}
2781+
Pat->forEachVariable([&](VarDecl *VD) { checkValueDecl(VD, Reason); });
28152782
}
28162783
void FindLocalVal::checkValueDecl(ValueDecl *D, DeclVisibilityKind Reason) {
28172784
if (!D)

test/IDE/complete_stmt_controlling_expr.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,3 +547,23 @@ func testGuardCase(x:FooStruct?) {
547547
// OPTIONAL_FOOSTRUCT-DAG: Decl[EnumElement]/CurrNominal/IsSystem/TypeRelation[Identical]: none[#Optional<FooStruct>#]; name=none
548548
// OPTIONAL_FOOSTRUCT-DAG: Decl[EnumElement]/CurrNominal/IsSystem/TypeRelation[Identical]: some({#FooStruct#})[#Optional<FooStruct>#]; name=some()
549549
// OPTIONAL_FOOSTRUCT: End completions
550+
551+
func returnOpt() -> String? { nil }
552+
func returnOptTuple() -> (String, String)? { nil}
553+
func test_rdar86050684() {
554+
guard let local1 = returnOpt() else { return }
555+
guard let (local2, _) = returnOptTuple() else { return }
556+
if let (local3, _) = returnOptTuple() {
557+
if case (let local4, _)? = returnOptTuple() {
558+
let (local5, _) = returnOptTuple() ?? ("", "")
559+
_ = #^RDAR86050684^#
560+
// RDAR86050684: Begin completions
561+
// RDAR86050684-DAG: Decl[LocalVar]/Local: local1[#String#];
562+
// RDAR86050684-DAG: Decl[LocalVar]/Local: local2[#String#];
563+
// RDAR86050684-DAG: Decl[LocalVar]/Local: local3[#String#];
564+
// RDAR86050684-DAG: Decl[LocalVar]/Local: local4[#String#];
565+
// RDAR86050684-DAG: Decl[LocalVar]/Local: local5[#String#];
566+
// RDAR86050684: End completions
567+
}
568+
}
569+
}

0 commit comments

Comments
 (0)