File tree Expand file tree Collapse file tree 5 files changed +31
-3
lines changed Expand file tree Collapse file tree 5 files changed +31
-3
lines changed Original file line number Diff line number Diff line change @@ -2713,6 +2713,10 @@ class ValueDecl : public Decl {
2713
2713
AccessSemantics getAccessSemanticsFromContext (const DeclContext *DC,
2714
2714
bool isAccessOnSelf) const ;
2715
2715
2716
+ // / Determines if a reference to this declaration from a nested function
2717
+ // / should be treated like a capture of a local value.
2718
+ bool isLocalCapture () const ;
2719
+
2716
2720
// / Print a reference to the given declaration.
2717
2721
std::string printRef () const ;
2718
2722
Original file line number Diff line number Diff line change @@ -57,7 +57,7 @@ CaptureInfo CaptureInfo::empty() {
57
57
58
58
bool CaptureInfo::hasLocalCaptures () const {
59
59
for (auto capture : getCaptures ())
60
- if (capture.getDecl ()->getDeclContext ()-> isLocalContext ())
60
+ if (capture.getDecl ()->isLocalCapture ())
61
61
return true ;
62
62
return false ;
63
63
}
@@ -71,7 +71,7 @@ getLocalCaptures(SmallVectorImpl<CapturedValue> &Result) const {
71
71
72
72
// Filter out global variables.
73
73
for (auto capture : getCaptures ()) {
74
- if (!capture.getDecl ()->getDeclContext ()-> isLocalContext ())
74
+ if (!capture.getDecl ()->isLocalCapture ())
75
75
continue ;
76
76
77
77
Result.push_back (capture);
Original file line number Diff line number Diff line change @@ -2866,6 +2866,16 @@ bool ValueDecl::isImplicitlyUnwrappedOptional() const {
2866
2866
false );
2867
2867
}
2868
2868
2869
+ bool ValueDecl::isLocalCapture () const {
2870
+ auto *dc = getDeclContext ();
2871
+
2872
+ if (auto *fd = dyn_cast<FuncDecl>(this ))
2873
+ if (isa<SourceFile>(dc))
2874
+ return fd->hasTopLevelLocalContextCaptures ();
2875
+
2876
+ return dc->isLocalContext ();
2877
+ }
2878
+
2869
2879
ArrayRef<ValueDecl *>
2870
2880
ValueDecl::getSatisfiedProtocolRequirements (bool Sorted) const {
2871
2881
// Dig out the nominal type.
Original file line number Diff line number Diff line change @@ -312,7 +312,7 @@ class FindCapturedVars : public ASTWalker {
312
312
313
313
// Only capture var decls at global scope. Other things can be captured
314
314
// if they are local.
315
- if (!isa<VarDecl>(D) && !DC-> isLocalContext ())
315
+ if (!isa<VarDecl>(D) && !D-> isLocalCapture ())
316
316
return { false , DRE };
317
317
318
318
// We're going to capture this, compute flags for the capture.
Original file line number Diff line number Diff line change
1
+ // RUN: %target-swift-frontend -emit-silgen %s | %FileCheck %s
2
+
3
+ guard let x: Int = nil else { while true { } }
4
+
5
+ // CHECK-LABEL: sil hidden [ossa] @$s18top_level_captures0C1XyyF : $@convention(thin) (Int) -> () {
6
+ func capturesX( ) {
7
+ _ = x
8
+ }
9
+
10
+ // CHECK-LABEL: sil hidden [ossa] @$s18top_level_captures17transitiveCaptureyyF : $@convention(thin) (Int) -> () {
11
+ // CHECK: [[FUNC:%.*]] = function_ref @$s18top_level_captures0C1XyyF : $@convention(thin) (Int) -> ()
12
+ func transitiveCapture( ) {
13
+ capturesX ( )
14
+ }
You can’t perform that action at this time.
0 commit comments