File tree Expand file tree Collapse file tree 2 files changed +75
-8
lines changed Expand file tree Collapse file tree 2 files changed +75
-8
lines changed Original file line number Diff line number Diff line change @@ -268,14 +268,30 @@ class BuilderClosureVisitor
268268 }
269269
270270 void visitPatternBindingDecl (PatternBindingDecl *patternBinding) {
271- // If any of the entries lacks an initializer, don't handle this node.
272- if (!llvm::all_of (range (patternBinding->getNumPatternEntries ()),
273- [&](unsigned index) {
274- return patternBinding->isExplicitlyInitialized (index);
275- })) {
276- if (!unhandledNode)
277- unhandledNode = patternBinding;
278- return ;
271+ // Enforce some restrictions on local variables inside a result builder.
272+ for (unsigned i : range (patternBinding->getNumPatternEntries ())) {
273+ // The pattern binding must have an initial value expression.
274+ if (!patternBinding->isExplicitlyInitialized (i)) {
275+ if (!unhandledNode)
276+ unhandledNode = patternBinding;
277+ return ;
278+ }
279+
280+ // Each variable bound by the pattern must be stored, and cannot
281+ // have observers.
282+ SmallVector<VarDecl *, 8 > variables;
283+ patternBinding->getPattern (i)->collectVariables (variables);
284+
285+ for (auto *var : variables) {
286+ if (!var->getImplInfo ().isSimpleStored ()) {
287+ if (!unhandledNode)
288+ unhandledNode = patternBinding;
289+ return ;
290+ }
291+
292+ // Also check for invalid attributes.
293+ TypeChecker::checkDeclAttributes (var);
294+ }
279295 }
280296
281297 // If there is a constraint system, generate constraints for the pattern
Original file line number Diff line number Diff line change 1+ // RUN: %target-typecheck-verify-swift
2+
3+ @resultBuilder
4+ struct DummyBuilder { // expected-note 5 {{struct 'DummyBuilder' declared here}}
5+ static func buildBlock< T> ( _ t: T ) -> T {
6+ return t
7+ }
8+ }
9+
10+ func dummy< T> ( @DummyBuilder _: ( ) -> T ) { }
11+
12+ dummy {
13+ var computedVar : Int { return 123 } // expected-error {{closure containing a declaration cannot be used with result builder 'DummyBuilder'}}
14+ ( )
15+ }
16+
17+ dummy {
18+ lazy var lazyVar : Int = 123 // expected-error {{closure containing a declaration cannot be used with result builder 'DummyBuilder'}}
19+ ( )
20+ }
21+
22+ dummy {
23+ var observedVar : Int = 123 { // expected-error {{closure containing a declaration cannot be used with result builder 'DummyBuilder'}}
24+ didSet { }
25+ }
26+
27+ ( )
28+ }
29+
30+ dummy {
31+ var observedVar : Int = 123 { // expected-error {{closure containing a declaration cannot be used with result builder 'DummyBuilder'}}
32+ willSet { }
33+ }
34+
35+ ( )
36+ }
37+
38+ @propertyWrapper struct Wrapper {
39+ var wrappedValue : Int
40+ }
41+
42+ dummy {
43+ @Wrapper var wrappedVar : Int = 123 // expected-error {{closure containing a declaration cannot be used with result builder 'DummyBuilder'}}
44+ ( )
45+ }
46+
47+ dummy {
48+ @resultBuilder var attributedVar : Int = 123 // expected-error {{@resultBuilder' attribute cannot be applied to this declaration}}
49+ // expected-warning@-1 {{variable 'attributedVar' was never used; consider replacing with '_' or removing it}}
50+ ( )
51+ }
You can’t perform that action at this time.
0 commit comments