Skip to content

Commit b42a33d

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 40eb19d commit b42a33d

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
@@ -485,7 +485,7 @@ bool BraceStmtScope::lookupLocalsOrMembers(ArrayRef<const ASTScopeImpl *>,
485485
bool PatternEntryInitializerScope::lookupLocalsOrMembers(
486486
ArrayRef<const ASTScopeImpl *>, DeclConsumer consumer) const {
487487
// 'self' is available within the pattern initializer of a 'lazy' variable.
488-
auto *initContext = cast_or_null<PatternBindingInitializer>(
488+
auto *initContext = dyn_cast_or_null<PatternBindingInitializer>(
489489
decl->getInitContext(0));
490490
if (initContext) {
491491
if (auto *selfParam = initContext->getImplicitSelfDecl()) {
@@ -782,7 +782,7 @@ Optional<bool> ClosureBodyScope::resolveIsCascadingUseForThisScope(
782782
Optional<bool> PatternEntryInitializerScope::resolveIsCascadingUseForThisScope(
783783
Optional<bool> isCascadingUse) const {
784784
auto *const initContext = getPatternEntry().getInitContext();
785-
auto *PBI = cast_or_null<PatternBindingInitializer>(initContext);
785+
auto *PBI = dyn_cast_or_null<PatternBindingInitializer>(initContext);
786786
auto *isd = PBI ? PBI->getImplicitSelfDecl() : nullptr;
787787

788788
// '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)