Skip to content

Commit ebdee21

Browse files
committed
Handle top-level vars' and closure params' access specially.
Parameters are normally given 'private' access, because they can only be referred to within the body of the owning function. However, single-expression closures allow a parameter to appear in a constraint system in the containing context. Mark closure parameters as 'fileprivate' instead. Similarly, 'private' at the top level is normally equivalent to 'fileprivate', but not for a decl that appears within top-level imperative code, which has a TopLevelCodeDecl context. This currently only happens for bindings in a top-level 'guard' statement; mark these variables and constants as 'fileprivate' as well. More progress on SE-0025 ('private' and 'fileprivate').
1 parent e4118f1 commit ebdee21

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,10 +1354,22 @@ void TypeChecker::computeAccessibility(ValueDecl *D) {
13541354
if (!D->hasAccessibility()) {
13551355
DeclContext *DC = D->getDeclContext();
13561356
switch (DC->getContextKind()) {
1357-
case DeclContextKind::SerializedLocal:
1357+
case DeclContextKind::TopLevelCodeDecl:
1358+
// Variables declared in a top-level 'guard' statement can be accessed in
1359+
// later top-level code.
1360+
D->setAccessibility(Accessibility::FilePrivate);
1361+
break;
13581362
case DeclContextKind::AbstractClosureExpr:
1363+
if (isa<ParamDecl>(D)) {
1364+
// Closure parameters may need to be accessible to the enclosing
1365+
// context, for single-expression closures.
1366+
D->setAccessibility(Accessibility::FilePrivate);
1367+
} else {
1368+
D->setAccessibility(Accessibility::Private);
1369+
}
1370+
break;
1371+
case DeclContextKind::SerializedLocal:
13591372
case DeclContextKind::Initializer:
1360-
case DeclContextKind::TopLevelCodeDecl:
13611373
case DeclContextKind::AbstractFunctionDecl:
13621374
case DeclContextKind::SubscriptDecl:
13631375
D->setAccessibility(Accessibility::Private);

test/expr/capture/top-level-guard.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ let closureCapture: () -> Void = { [x] in
3939
}
4040

4141
// CHECK-LABEL: (defer_stmt
42-
// CHECK-NEXT: (func_decl implicit "$defer()" type='() -> ()' access=private captures=(x<direct><noescape>)
42+
// CHECK-NEXT: (func_decl implicit "$defer()" type='() -> ()' access=fileprivate captures=(x<direct><noescape>)
4343
defer {
4444
_ = x
4545
}

0 commit comments

Comments
 (0)