Skip to content

Commit 508e825

Browse files
committed
Split 'fileprivate' and 'private', but give them the same behavior.
'fileprivate' is considered a broader level of access than 'private', but for now both of them are still available to the entire file. This is intended as a migration aid. One interesting fallout of the "access scope" model described in 758cf64 is that something declared 'private' at file scope is actually treated as 'fileprivate' for diagnostic purposes. This is something we can fix later, once the full model is in place. (It's not really /wrong/ in that they have identical behavior, but diagnostics still shouldn't refer to a type explicitly declared 'private' as 'fileprivate'.) As a note, ValueDecl::getEffectiveAccess will always return 'FilePrivate' rather than 'Private'; for purposes of optimization and code generation, we should never try to distinguish these two cases. This should have essentially no effect on code that's /not/ using 'fileprivate' other than altered diagnostics. Progress on SE-0025 ('fileprivate' and 'private')
1 parent 4f387e3 commit 508e825

40 files changed

+369
-243
lines changed

include/swift/AST/AttrKind.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,13 @@ enum class UnaryOperatorKind : uint8_t {
4646
};
4747

4848
/// Access control levels.
49-
// These are used in diagnostics, so please do not reorder existing values.
49+
// These are used in diagnostics and with < and similar operations,
50+
// so please do not reorder existing values.
5051
enum class Accessibility : uint8_t {
51-
/// Private access is limited to the current file.
52+
/// Private access is limited to the current scope.
5253
Private = 0,
54+
/// File-private access is limited to the current file.
55+
FilePrivate,
5356
/// Internal access is limited to the current module.
5457
Internal,
5558
/// Public access is not limited.

include/swift/AST/Decl.h

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -541,16 +541,16 @@ class alignas(1 << DeclAlignInBits) Decl {
541541

542542
/// An encoding of the default and maximum access level for this extension.
543543
///
544-
/// This is encoded as (1 << maxAccess) | (1 << defaultAccess), which
545-
/// works because the maximum is always greater than or equal to the
546-
/// default. 0 represents an uncomputed value.
544+
/// This is encoded as (1 << (maxAccess-1)) | (1 << (defaultAccess-1)),
545+
/// which works because the maximum is always greater than or equal to the
546+
/// default, and 'private' is never used. 0 represents an uncomputed value.
547547
unsigned DefaultAndMaxAccessLevel : 3;
548548

549549
/// Whether there is an active conformance loader for this
550550
/// extension.
551551
unsigned HaveConformanceLoader : 1;
552552
};
553-
enum { NumExtensionDeclBits = NumDeclBits + 5 };
553+
enum { NumExtensionDeclBits = NumDeclBits + 6 };
554554
static_assert(NumExtensionDeclBits <= 32, "fits in an unsigned");
555555

556556
protected:
@@ -1699,32 +1699,34 @@ class ExtensionDecl final : public Decl, public DeclContext,
16991699
Accessibility getDefaultAccessibility() const {
17001700
assert(hasDefaultAccessibility() && "not computed yet");
17011701
if (ExtensionDeclBits.DefaultAndMaxAccessLevel &
1702-
(1 << static_cast<unsigned>(Accessibility::Private)))
1703-
return Accessibility::Private;
1702+
(1 << (static_cast<unsigned>(Accessibility::FilePrivate) - 1)))
1703+
return Accessibility::FilePrivate;
17041704
if (ExtensionDeclBits.DefaultAndMaxAccessLevel &
1705-
(1 << static_cast<unsigned>(Accessibility::Internal)))
1705+
(1 << (static_cast<unsigned>(Accessibility::Internal) - 1)))
17061706
return Accessibility::Internal;
17071707
return Accessibility::Public;
17081708
}
17091709

17101710
Accessibility getMaxAccessibility() const {
17111711
assert(hasDefaultAccessibility() && "not computed yet");
17121712
if (ExtensionDeclBits.DefaultAndMaxAccessLevel &
1713-
(1 << static_cast<unsigned>(Accessibility::Public)))
1713+
(1 << (static_cast<unsigned>(Accessibility::Public) - 1)))
17141714
return Accessibility::Public;
17151715
if (ExtensionDeclBits.DefaultAndMaxAccessLevel &
1716-
(1 << static_cast<unsigned>(Accessibility::Internal)))
1716+
(1 << (static_cast<unsigned>(Accessibility::Internal) - 1)))
17171717
return Accessibility::Internal;
1718-
return Accessibility::Private;
1718+
return Accessibility::FilePrivate;
17191719
}
17201720

17211721
void setDefaultAndMaxAccessibility(Accessibility defaultAccess,
17221722
Accessibility maxAccess) {
17231723
assert(!hasDefaultAccessibility() && "default accessibility already set");
17241724
assert(maxAccess >= defaultAccess);
1725+
assert(maxAccess != Accessibility::Private && "private not valid");
1726+
assert(defaultAccess != Accessibility::Private && "private not valid");
17251727
ExtensionDeclBits.DefaultAndMaxAccessLevel =
1726-
(1 << static_cast<unsigned>(defaultAccess)) |
1727-
(1 << static_cast<unsigned>(maxAccess));
1728+
(1 << (static_cast<unsigned>(defaultAccess) - 1)) |
1729+
(1 << (static_cast<unsigned>(maxAccess) - 1));
17281730
assert(getDefaultAccessibility() == defaultAccess && "not enough bits");
17291731
assert(getMaxAccessibility() == maxAccess && "not enough bits");
17301732
}
@@ -2084,7 +2086,7 @@ class IfConfigDecl : public Decl {
20842086
class ValueDecl : public Decl {
20852087
DeclName Name;
20862088
SourceLoc NameLoc;
2087-
llvm::PointerIntPair<Type, 2, OptionalEnum<Accessibility>> TypeAndAccess;
2089+
llvm::PointerIntPair<Type, 3, OptionalEnum<Accessibility>> TypeAndAccess;
20882090

20892091
protected:
20902092
ValueDecl(DeclKind K,
@@ -3873,8 +3875,8 @@ class AbstractStorageDecl : public ValueDecl {
38733875
void configureObservingRecord(ObservingRecord *record,
38743876
FuncDecl *willSet, FuncDecl *didSet);
38753877

3876-
llvm::PointerIntPair<GetSetRecord*, 2, OptionalEnum<Accessibility>> GetSetInfo;
3877-
llvm::PointerIntPair<BehaviorRecord*, 2, OptionalEnum<Accessibility>>
3878+
llvm::PointerIntPair<GetSetRecord*, 3, OptionalEnum<Accessibility>> GetSetInfo;
3879+
llvm::PointerIntPair<BehaviorRecord*, 3, OptionalEnum<Accessibility>>
38783880
BehaviorInfo;
38793881

38803882
ObservingRecord &getDidSetInfo() const {

include/swift/AST/DiagnosticsSema.def

Lines changed: 72 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,14 @@ ERROR(could_not_use_member_on_existential,none,
108108
(Type, DeclName))
109109

110110
ERROR(candidate_inaccessible,none,
111-
"%0 is inaccessible due to '%select{private|internal|PUBLIC}1' "
112-
"protection level", (DeclName, Accessibility))
111+
"%0 is inaccessible due to "
112+
"'%select{private|fileprivate|internal|PUBLIC}1' protection level",
113+
(DeclName, Accessibility))
113114

114115
ERROR(init_candidate_inaccessible,none,
115-
"%0 initializer is inaccessible due to '%select{private|internal|PUBLIC}1' "
116-
"protection level", (Type, Accessibility))
116+
"%0 initializer is inaccessible due to "
117+
"'%select{private|fileprivate|internal|PUBLIC}1' protection level",
118+
(Type, Accessibility))
117119

118120

119121
ERROR(cannot_pass_rvalue_mutating_subelement,none,
@@ -940,30 +942,31 @@ ERROR(attr_methods_only,none,
940942
ERROR(access_control_in_protocol,none,
941943
"%0 modifier cannot be used in protocols", (DeclAttribute))
942944
ERROR(access_control_setter,none,
943-
"'%select{private|internal|public}0(set)' modifier can only be applied "
944-
"to variables and subscripts",
945+
"'%select{private|fileprivate|internal|public}0(set)' modifier can only "
946+
"be applied to variables and subscripts",
945947
(Accessibility))
946948
ERROR(access_control_setter_read_only,none,
947-
"'%select{private|internal|public}0(set)' modifier cannot be applied to "
948-
"%select{constants|read-only variables|read-only properties"
949+
"'%select{private|fileprivate|internal|public}0(set)' modifier cannot be "
950+
"applied to %select{constants|read-only variables|read-only properties"
949951
"|read-only subscripts}1",
950952
(Accessibility, unsigned))
951953
ERROR(access_control_setter_more,none,
952-
"%select{private|internal|PUBLIC}0 "
954+
"%select{private|fileprivate|internal|PUBLIC}0 "
953955
"%select{variable|property|subscript}1 cannot have "
954-
"%select{PRIVATE|an internal|a public}2 setter",
956+
"%select{PRIVATE|a fileprivate|an internal|a public}2 setter",
955957
(Accessibility, unsigned, Accessibility))
956958
WARNING(access_control_ext_member_more,none,
957-
"declaring %select{PRIVATE|an internal|a public}0 %1 in "
958-
"%select{a private|an internal|PUBLIC}2 extension",
959+
"declaring %select{PRIVATE|a fileprivate|an internal|a public}0 %1 in "
960+
"%select{a private|a fileprivate|an internal|PUBLIC}2 extension",
959961
(Accessibility, DescriptiveDeclKind, Accessibility))
960962
ERROR(access_control_ext_requirement_member_more,none,
961-
"cannot declare %select{PRIVATE|an internal|a public}0 %1 in "
962-
"an extension with %select{private|internal|PUBLIC}2 requirements",
963+
"cannot declare %select{PRIVATE|a fileprivate|an internal|a public}0 %1 "
964+
"in an extension with %select{private|fileprivate|internal|PUBLIC}2 "
965+
"requirements",
963966
(Accessibility, DescriptiveDeclKind, Accessibility))
964967
ERROR(access_control_extension_more,none,
965-
"extension of %select{private|internal|PUBLIC}0 %1 cannot be "
966-
"declared %select{PRIVATE|internal|public}2",
968+
"extension of %select{private|fileprivate|internal|PUBLIC}0 %1 cannot "
969+
"be declared %select{PRIVATE|fileprivate|internal|public}2",
967970
(Accessibility, DescriptiveDeclKind, Accessibility))
968971

969972
ERROR(invalid_decl_attribute_simple,none,
@@ -1051,15 +1054,17 @@ ERROR(static_requires_initializer,none,
10511054
"expression or getter/setter specifier", (StaticSpellingKind))
10521055
ERROR(pattern_type_access,none,
10531056
"%select{%select{variable|constant}0|property}1 "
1054-
"%select{must be declared %select{private|internal|PUBLIC}4"
1055-
"|cannot be declared %select{PRIVATE|internal|public}3}2 because its "
1056-
"type uses %select{a private|an internal|PUBLIC}4 type",
1057+
"%select{must be declared %select{private|fileprivate|internal|PUBLIC}4"
1058+
"|cannot be declared %select{PRIVATE|fileprivate|internal|public}3}2 "
1059+
"because its type uses "
1060+
"%select{a private|a fileprivate|an internal|PUBLIC}4 type",
10571061
(bool, bool, bool, Accessibility, Accessibility))
10581062
ERROR(pattern_type_access_inferred,none,
10591063
"%select{%select{variable|constant}0|property}1 "
1060-
"%select{must be declared %select{private|internal|PUBLIC}4"
1061-
"|cannot be declared %select{PRIVATE|internal|public}3}2 because its "
1062-
"type %5 uses %select{a private|an internal|PUBLIC}4 type",
1064+
"%select{must be declared %select{private|fileprivate|internal|PUBLIC}4"
1065+
"|cannot be declared %select{PRIVATE|fileprivate|internal|public}3}2 "
1066+
"because its type %5 uses "
1067+
"%select{a private|a fileprivate|an internal|PUBLIC}4 type",
10631068
(bool, bool, bool, Accessibility, Accessibility, Type))
10641069
ERROR(pattern_binds_no_variables,none,
10651070
"%select{property|global variable}0 declaration does not bind any "
@@ -1094,26 +1099,29 @@ ERROR(unsupported_nested_protocol,none,
10941099
ERROR(circular_type_alias,none,
10951100
"type alias %0 circularly references itself", (Identifier))
10961101
ERROR(type_alias_underlying_type_access,none,
1097-
"type alias %select{must be declared %select{private|internal|PUBLIC}2"
1098-
"|cannot be declared %select{PRIVATE|internal|public}1}0 because its "
1099-
"underlying type uses %select{a private|an internal|PUBLIC}2 type",
1102+
"type alias %select{must be declared "
1103+
"%select{private|fileprivate|internal|PUBLIC}2"
1104+
"|cannot be declared %select{PRIVATE|fileprivate|internal|public}1}0 "
1105+
"because its underlying type uses "
1106+
"%select{a private|a fileprivate|an internal|PUBLIC}2 type",
11001107
(bool, Accessibility, Accessibility))
11011108

11021109
// Subscripts
11031110
ERROR(subscript_type_access,none,
1104-
"subscript %select{must be declared %select{private|internal|PUBLIC}2"
1105-
"|cannot be declared %select{PRIVATE|internal|public}1}0 because its "
1106-
"%select{index|element type}3 uses "
1107-
"%select{a private|an internal|PUBLIC}2 type",
1111+
"subscript %select{must be declared "
1112+
"%select{private|fileprivate|internal|PUBLIC}2"
1113+
"|cannot be declared %select{PRIVATE|fileprivate|internal|public}1}0 "
1114+
"because its %select{index|element type}3 uses "
1115+
"%select{a private|a fileprivate|an internal|PUBLIC}2 type",
11081116
(bool, Accessibility, Accessibility, bool))
11091117

11101118
// Functions
11111119
ERROR(function_type_access,none,
11121120
"%select{function|method|initializer}3 "
1113-
"%select{must be declared %select{private|internal|PUBLIC}2"
1114-
"|cannot be declared %select{PRIVATE|internal|public}1}0 because its "
1115-
"%select{parameter|result}4 uses "
1116-
"%select{a private|an internal|PUBLIC}2 type",
1121+
"%select{must be declared %select{private|fileprivate|internal|PUBLIC}2"
1122+
"|cannot be declared %select{PRIVATE|fileprivate|internal|public}1}0 "
1123+
"because its %select{parameter|result}4 uses "
1124+
"%select{a private|a fileprivate|an internal|PUBLIC}2 type",
11171125
(bool, Accessibility, Accessibility, unsigned, bool))
11181126
WARNING(non_trailing_closure_before_default_args,none,
11191127
"closure parameter prior to parameters with default arguments will "
@@ -1220,28 +1228,30 @@ ERROR(witness_requires_dynamic_self,none,
12201228
ERROR(witness_not_accessible_proto,none,
12211229
"%select{initializer %1|method %1|%select{|setter for }2property %1"
12221230
"|subscript%select{| setter}2}0 must be declared "
1223-
"%select{PRIVATE|internal|public}3 because it matches a requirement "
1224-
"in %select{PRIVATE|internal|public}3 protocol %4",
1231+
"%select{PRIVATE|fileprivate|internal|public}3 because it matches a "
1232+
"requirement in %select{PRIVATE|fileprivate|internal|public}3 protocol "
1233+
"%4",
12251234
(RequirementKind, DeclName, bool, Accessibility, DeclName))
12261235
ERROR(witness_not_accessible_type,none,
12271236
"%select{initializer %1|method %1|%select{|setter for }2property %1"
12281237
"|subscript%select{| setter}2}0 must be as accessible as its enclosing "
12291238
"type because it matches a requirement in protocol %4",
12301239
(RequirementKind, DeclName, bool, Accessibility, DeclName))
12311240
ERROR(type_witness_not_accessible_proto,none,
1232-
"%0 %1 must be declared %select{PRIVATE|internal|public}2 because it "
1233-
"matches a requirement in %select{PRIVATE|internal|public}2 protocol %3",
1241+
"%0 %1 must be declared %select{PRIVATE|fileprivate|internal|public}2 "
1242+
"because it matches a requirement in "
1243+
"%select{PRIVATE|fileprivate|internal|public}2 protocol %3",
12341244
(DescriptiveDeclKind, DeclName, Accessibility, DeclName))
12351245
ERROR(type_witness_not_accessible_type,none,
12361246
"%0 %1 must be as accessible as its enclosing type because it "
12371247
"matches a requirement in protocol %3",
12381248
(DescriptiveDeclKind, DeclName, Accessibility, DeclName))
12391249

12401250
ERROR(protocol_refine_access,none,
1241-
"%select{protocol must be declared %select{private|internal|PUBLIC}2 "
1242-
"because it refines"
1243-
"|%select{PRIVATE|internal|public}1 protocol cannot refine}0 "
1244-
"%select{a private|an internal|PUBLIC}2 protocol",
1251+
"%select{protocol must be declared "
1252+
"%select{private|fileprivate|internal|PUBLIC}2 because it refines"
1253+
"|%select{PRIVATE|fileprivate|internal|public}1 protocol cannot "
1254+
"refine}0 %select{a private|a fileprivate|an internal|PUBLIC}2 protocol",
12451255
(bool, Accessibility, Accessibility))
12461256
ERROR(protocol_property_must_be_computed_var,none,
12471257
"immutable property requirement must be declared as 'var' with a "
@@ -1270,8 +1280,9 @@ NOTE(default_associated_type_req_fail,none,
12701280
"does not conform to %3",
12711281
(Type, DeclName, Type, Type))
12721282
ERROR(associated_type_access,none,
1273-
"associated type in %select{PRIVATE|an internal|a public}0 protocol "
1274-
"uses %select{a private|an internal|PUBLIC}1 type in its "
1283+
"associated type in "
1284+
"%select{PRIVATE|a fileprivate|an internal|a public}0 protocol uses "
1285+
"%select{a private|a fileprivate|an internal|PUBLIC}1 type in its "
12751286
"%select{default definition|requirement}2 ",
12761287
(Accessibility, Accessibility, unsigned))
12771288

@@ -1373,7 +1384,7 @@ NOTE(optional_req_near_match_move,none,
13731384
NOTE(optional_req_near_match_nonobjc,none,
13741385
"add '@nonobjc' to silence this %select{warning|error}0", (bool))
13751386
NOTE(optional_req_near_match_accessibility,none,
1376-
"make %0 %select{ERROR|private|private or internal}1 to silence this "
1387+
"make %0 %select{ERROR|private|private|non-public}1 to silence this "
13771388
"warning", (DeclName, Accessibility))
13781389

13791390
// Protocols and existentials
@@ -1425,10 +1436,11 @@ ERROR(requires_generic_param_same_type_does_not_conform,none,
14251436
(Type, Identifier))
14261437

14271438
ERROR(generic_param_access,none,
1428-
"%0 %select{must be declared %select{private|internal|PUBLIC}3"
1429-
"|cannot be declared %select{PRIVATE|internal|public}2}1 because its "
1430-
"generic %select{parameter|requirement}4 uses "
1431-
"%select{a private|an internal|PUBLIC}3 type",
1439+
"%0 %select{must be declared "
1440+
"%select{private|fileprivate|internal|PUBLIC}3"
1441+
"|cannot be declared %select{PRIVATE|fileprivate|internal|public}2}1 "
1442+
"because its generic %select{parameter|requirement}4 uses "
1443+
"%select{a private|a fileprivate|an internal|PUBLIC}3 type",
14321444
(DescriptiveDeclKind, bool, Accessibility, Accessibility, bool))
14331445

14341446
ERROR(override_multiple_decls_base,none,
@@ -1607,8 +1619,8 @@ ERROR(inheritance_from_objc_runtime_visible_class,none,
16071619

16081620
// Enums
16091621
ERROR(enum_case_access,none,
1610-
"enum case in %select{PRIVATE|an internal|a public}0 enum uses "
1611-
"%select{a private|an internal|PUBLIC}1 type",
1622+
"enum case in %select{PRIVATE|a fileprivate|an internal|a public}0 enum "
1623+
"uses %select{a private|a fileprivate|an internal|PUBLIC}1 type",
16121624
(Accessibility, Accessibility))
16131625
ERROR(enum_stored_property,none,
16141626
"enums may not contain stored properties", ())
@@ -1627,9 +1639,11 @@ ERROR(enum_raw_type_not_equatable,none,
16271639
"RawRepresentable 'init' cannot be synthesized because raw type %0 is not "
16281640
"Equatable", (Type))
16291641
ERROR(enum_raw_type_access,none,
1630-
"enum %select{must be declared %select{private|internal|PUBLIC}2"
1631-
"|cannot be declared %select{PRIVATE|internal|public}1}0 because its "
1632-
"raw type uses %select{a private|an internal|PUBLIC}2 type",
1642+
"enum %select{must be declared "
1643+
"%select{private|fileprivate|internal|PUBLIC}2"
1644+
"|cannot be declared %select{PRIVATE|fileprivate|internal|public}1}0 "
1645+
"because its raw type uses "
1646+
"%select{a private|a fileprivate|an internal|PUBLIC}2 type",
16331647
(bool, Accessibility, Accessibility))
16341648

16351649
NOTE(enum_here,none,
@@ -2538,9 +2552,11 @@ ERROR(self_in_nominal,none,
25382552
"'Self' is only available in a protocol or as the result of a "
25392553
"method in a class; did you mean %0?", (Identifier))
25402554
ERROR(class_super_access,none,
2541-
"class %select{must be declared %select{private|internal|PUBLIC}2"
2542-
"|cannot be declared %select{PRIVATE|internal|public}1}0 because its "
2543-
"superclass is %select{private|internal|PUBLIC}2",
2555+
"class %select{must be declared "
2556+
"%select{private|fileprivate|internal|PUBLIC}2"
2557+
"|cannot be declared %select{PRIVATE|fileprivate|internal|public}1}0 "
2558+
"because its superclass is "
2559+
"%select{private|fileprivate|internal|PUBLIC}2",
25442560
(bool, Accessibility, Accessibility))
25452561
ERROR(dot_protocol_on_non_existential,none,
25462562
"cannot use 'Protocol' with non-protocol type %0", (Type))

include/swift/Serialization/ModuleFormat.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ const uint16_t VERSION_MAJOR = 0;
5353
/// in source control, you should also update the comment to briefly
5454
/// describe what change you made. The content of this comment isn't important;
5555
/// it just ensures a conflict if two people change the module format.
56-
const uint16_t VERSION_MINOR = 256; // Last change: remove noreturn bit
56+
const uint16_t VERSION_MINOR = 257; // Last change: private/fileprivate
5757

5858
using DeclID = PointerEmbeddedInt<unsigned, 31>;
5959
using DeclIDField = BCFixed<31>;
@@ -287,6 +287,7 @@ using LibraryKindField = BCFixed<1>;
287287
// VERSION_MAJOR.
288288
enum class AccessibilityKind : uint8_t {
289289
Private = 0,
290+
FilePrivate,
290291
Internal,
291292
Public,
292293
};

lib/AST/ASTDumper.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,9 @@ namespace {
570570
case Accessibility::Private:
571571
OS << "private";
572572
break;
573+
case Accessibility::FilePrivate:
574+
OS << "fileprivate";
575+
break;
573576
case Accessibility::Internal:
574577
OS << "internal";
575578
break;

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,9 @@ class PrintAST : public ASTVisitor<PrintAST> {
11351135
case Accessibility::Private:
11361136
Printer << tok::kw_private;
11371137
break;
1138+
case Accessibility::FilePrivate:
1139+
Printer << tok::kw_fileprivate;
1140+
break;
11381141
case Accessibility::Internal:
11391142
if (!Options.PrintInternalAccessibilityKeyword)
11401143
return;

0 commit comments

Comments
 (0)