Skip to content

Commit 5e3ef64

Browse files
committed
AST: Fix ASTScopeLookup crash if a PatternBindingEntry's context is not a PatternBindingInitializer
The function builder transform creates pattern bindings parented in other DeclContexts. If those pattern binding initializer expressions in turn contain multi-statement closures, we will try to perform unqualified lookups from those contexts when we get around to type checking the closure body. Change some unconditional casts to conditional casts in ASTScope lookup, to handle this case. The casts are only performed while checking if the initializer context is part of a 'lazy' property, which doesn't apply here. Fixes <rdar://problem/67265731>.
1 parent 995eb66 commit 5e3ef64

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

lib/AST/ASTScopeLookup.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ bool BraceStmtScope::lookupLocalsOrMembers(ArrayRef<const ASTScopeImpl *>,
519519
bool PatternEntryInitializerScope::lookupLocalsOrMembers(
520520
ArrayRef<const ASTScopeImpl *>, DeclConsumer consumer) const {
521521
// 'self' is available within the pattern initializer of a 'lazy' variable.
522-
auto *initContext = cast_or_null<PatternBindingInitializer>(
522+
auto *initContext = dyn_cast_or_null<PatternBindingInitializer>(
523523
decl->getInitContext(0));
524524
if (initContext) {
525525
if (auto *selfParam = initContext->getImplicitSelfDecl()) {
@@ -816,7 +816,7 @@ Optional<bool> ClosureBodyScope::resolveIsCascadingUseForThisScope(
816816
Optional<bool> PatternEntryInitializerScope::resolveIsCascadingUseForThisScope(
817817
Optional<bool> isCascadingUse) const {
818818
auto *const initContext = getPatternEntry().getInitContext();
819-
auto *PBI = cast_or_null<PatternBindingInitializer>(initContext);
819+
auto *PBI = dyn_cast_or_null<PatternBindingInitializer>(initContext);
820820
auto *isd = PBI ? PBI->getImplicitSelfDecl() : nullptr;
821821

822822
// 'self' is available within the pattern initializer of a 'lazy' variable.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %target-swift-frontend -typecheck %s
2+
3+
@_functionBuilder
4+
struct SillyBuilder {
5+
static func buildBlock() -> () {}
6+
}
7+
8+
struct SillyStruct {
9+
init(@SillyBuilder _: () -> ()) {}
10+
}
11+
12+
struct UsesSillyStruct {
13+
var x: Int = 0
14+
15+
func foo() {
16+
SillyStruct {
17+
let fn = {
18+
if true {
19+
_ = x
20+
}
21+
}
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)