Skip to content

Commit 01bc774

Browse files
committed
Sema: Enforce that stored properties of @_fixed_layout classes only reference public types
This is the same restriction as with @Frozen structs. Even though classes are lowered as a single reference and clients don't usually manipulate their stored property layout directly, @Frozen classes can have @inlinable designated initializers.
1 parent b4c568e commit 01bc774

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

lib/Sema/TypeCheckAccess.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,15 +1051,16 @@ class UsableFromInlineChecker : public AccessControlCheckerBase,
10511051
UNINTERESTING(Accessor) // Handled by the Var or Subscript.
10521052
UNINTERESTING(OpaqueType) // Handled by the Var or Subscript.
10531053

1054-
/// If \p VD's layout is exposed by a @frozen struct, return said struct.
1054+
/// If \p VD's layout is exposed by a @frozen struct or class, return said
1055+
/// struct or class.
10551056
///
1056-
/// Stored instance properties in @frozen structs must always use
1057+
/// Stored instance properties in @frozen structs and classes must always use
10571058
/// public/@usableFromInline types. In these cases, check the access against
10581059
/// the struct instead of the VarDecl, and customize the diagnostics.
10591060
static const ValueDecl *
10601061
getFixedLayoutStructContext(const VarDecl *VD) {
10611062
if (VD->isLayoutExposedToClients())
1062-
return dyn_cast<StructDecl>(VD->getDeclContext());
1063+
return dyn_cast<NominalTypeDecl>(VD->getDeclContext());
10631064

10641065
return nullptr;
10651066
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5
2+
3+
private struct PrivateType {}
4+
// expected-note@-1 {{struct 'PrivateType' is not '@usableFromInline' or public}}
5+
// expected-note@-2 {{initializer 'init()' is not '@usableFromInline' or public}}
6+
// expected-note@-3 {{type declared here}}
7+
8+
@_fixed_layout public class UsesPrivateType {
9+
private var y1: PrivateType
10+
// expected-error@-1 {{type referenced from a stored property in a '@frozen' struct must be '@usableFromInline' or public}}
11+
12+
private var y2 = PrivateType()
13+
// expected-error@-1 {{struct 'PrivateType' is private and cannot be referenced from a property initializer in a '@frozen' type}}
14+
// expected-error@-2 {{initializer 'init()' is private and cannot be referenced from a property initializer in a '@frozen' type}}
15+
// expected-error@-3 {{type referenced from a stored property with inferred type 'PrivateType' in a '@frozen' struct must be '@usableFromInline' or public}}
16+
17+
init() {}
18+
}

0 commit comments

Comments
 (0)