Skip to content

Commit 76d5dd4

Browse files
authored
Merge pull request #72857 from li3zhen1/fix-init-accessor-71578
[AccessRequests] Allow Init accessor to be `internal`
2 parents 70c54bb + afa66b1 commit 76d5dd4

File tree

7 files changed

+92
-8
lines changed

7 files changed

+92
-8
lines changed

include/swift/AST/DiagnosticsParse.def

+4
Original file line numberDiff line numberDiff line change
@@ -2158,6 +2158,10 @@ ERROR(init_accessor_is_not_on_property,none,
21582158
"init accessors could only be associated with properties",
21592159
())
21602160

2161+
ERROR(init_accessor_is_not_in_the_primary_declaration,none,
2162+
"init accessors cannot be declared in an extension",
2163+
())
2164+
21612165
ERROR(missing_storage_restrictions_attr_label,none,
21622166
"missing label in @storageRestrictions attribute", ())
21632167

lib/AST/AccessRequests.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ AccessLevelRequest::evaluate(Evaluator &evaluator, ValueDecl *D) const {
6565
// These are only needed to synthesize the setter.
6666
return AccessLevel::Private;
6767
case AccessorKind::Init:
68-
// These are only called from designated initializers.
69-
return AccessLevel::Private;
68+
// These are only called from within the same module.
69+
return std::min(storage->getFormalAccess(), AccessLevel::Internal);
7070
}
7171
}
7272

lib/Parse/ParseDecl.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -8497,8 +8497,11 @@ void Parser::ParsedAccessors::classify(Parser &P, AbstractStorageDecl *storage,
84978497
}
84988498

84998499
if (Init) {
8500-
if (!storage->getDeclContext()->getSelfNominalTypeDecl() ||
8501-
isa<SubscriptDecl>(storage)) {
8500+
auto *DC = storage->getDeclContext();
8501+
if (isa<ExtensionDecl>(DC)) {
8502+
P.diagnose(Init->getLoc(),
8503+
diag::init_accessor_is_not_in_the_primary_declaration);
8504+
} else if (!DC->isTypeContext() || isa<SubscriptDecl>(storage)) {
85028505
P.diagnose(Init->getLoc(), diag::init_accessor_is_not_on_property);
85038506
}
85048507
}

test/SILOptimizer/init_accessors.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ struct TestInit {
1010
var full: (Int, Int)
1111

1212
var point: (Int, Int) {
13-
// CHECK-LABEL: sil private [ossa] @$s14init_accessors8TestInitV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int, @thin TestInit.Type) -> (@out Int, @out (Int, Int))
13+
// CHECK-LABEL: sil hidden [ossa] @$s14init_accessors8TestInitV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int, @thin TestInit.Type) -> (@out Int, @out (Int, Int))
1414
// CHECK: bb0([[Y_REF:%.*]] : $*Int, [[FULL_REF:%.*]] : $*(Int, Int), [[X_VAL:%.*]] : $Int, [[Y_VAL:%.*]] : $Int, [[X_REF:%.*]] : $*Int, [[METATYPE:%.*]] : $@thin TestInit.Type):
1515
//
1616
// CHECK: [[INITIAL_VALUE:%.*]] = tuple ([[X_VAL]] : $Int, [[Y_VAL]] : $Int)
@@ -230,7 +230,7 @@ class TestClass {
230230
var y: (Int, [String])
231231

232232
var data: (Int, (Int, [String])) {
233-
// CHECK-LABEL: sil private [ossa] @$s14init_accessors9TestClassC4dataSi_Si_SaySSGttvi : $@convention(thin) (Int, Int, @owned Array<String>, @thick TestClass.Type) -> (@out Int, @out (Int, Array<String>))
233+
// CHECK-LABEL: sil hidden [ossa] @$s14init_accessors9TestClassC4dataSi_Si_SaySSGttvi : $@convention(thin) (Int, Int, @owned Array<String>, @thick TestClass.Type) -> (@out Int, @out (Int, Array<String>))
234234
// CHECK: bb0([[X_REF:%.*]] : $*Int, [[Y_REF:%.*]] : $*(Int, Array<String>), [[X_VAL:%.*]] : $Int, [[Y_VAL_0:%.*]] : $Int, [[Y_VAL_1:%.*]] : @owned $Array<String>, [[METATYPE:%.*]] : $@thick TestClass.Type):
235235
//
236236
// CHECK: ([[X_VAL:%.*]], [[Y_VAL:%.*]]) = destructure_tuple {{.*}} : $(Int, (Int, Array<String>))
@@ -277,7 +277,7 @@ struct TestGeneric<T, U> {
277277
var b: T
278278
var c: U
279279

280-
// CHECK-LABEL: sil private [ossa] @$s14init_accessors11TestGenericV4datax_xtvi : $@convention(thin) <T, U> (@in T, @in T, @inout U, @thin TestGeneric<T, U>.Type) -> (@out T, @out T)
280+
// CHECK-LABEL: sil hidden [ossa] @$s14init_accessors11TestGenericV4datax_xtvi : $@convention(thin) <T, U> (@in T, @in T, @inout U, @thin TestGeneric<T, U>.Type) -> (@out T, @out T)
281281
//
282282
// CHECK: bb0([[A_REF:%.*]] : $*T, [[B_REF:%.*]] : $*T, [[A_VALUE:%.*]] : $*T, [[B_VALUE:%.*]] : $*T, [[C_REF:%.*]] : $*U, [[METATYPE:%.*]] : $@thin TestGeneric<T, U>.Type):
283283
//
@@ -326,7 +326,7 @@ struct TestGenericTuple<T, U> {
326326
var a: T
327327
var b: (T, U)
328328

329-
// CHECK-LABEL: sil private [ossa] @$s14init_accessors16TestGenericTupleV4datax_x_q_ttvi : $@convention(thin) <T, U> (@in T, @in T, @in U, @thin TestGenericTuple<T, U>.Type) -> (@out T, @out (T, U)) {
329+
// CHECK-LABEL: sil hidden [ossa] @$s14init_accessors16TestGenericTupleV4datax_x_q_ttvi : $@convention(thin) <T, U> (@in T, @in T, @in U, @thin TestGenericTuple<T, U>.Type) -> (@out T, @out (T, U)) {
330330
//
331331
// CHECK: bb0([[A_REF:%.*]] : $*T, [[B_REF:%.*]] : $*(T, U), [[A_VALUE:%.*]] : $*T, [[B_VALUE:%.*]] : $*T, [[C_VALUE:%.*]] : $*U, [[METATYPE:%.*]] : $@thin TestGenericTuple<T, U>.Type):
332332
//
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
struct S {
2+
var _x: Int
3+
public var xImmutablePublic: Int {
4+
@storageRestrictions(initializes: _x)
5+
init {
6+
_x = initialValue
7+
}
8+
get {
9+
return _x
10+
}
11+
}
12+
13+
public var xMutablePublic: Int {
14+
@storageRestrictions(initializes: _x)
15+
init {
16+
_x = initialValue
17+
}
18+
get {
19+
return _x
20+
}
21+
set {
22+
_x = newValue
23+
}
24+
}
25+
26+
internal var xImmutableInternal: Int {
27+
@storageRestrictions(initializes: _x)
28+
init {
29+
_x = initialValue
30+
}
31+
get {
32+
return _x
33+
}
34+
}
35+
36+
internal var xMutableInternal: Int {
37+
@storageRestrictions(initializes: _x)
38+
init {
39+
_x = initialValue
40+
}
41+
get {
42+
return _x
43+
}
44+
set {
45+
_x = newValue
46+
}
47+
}
48+
}

test/decl/var/init_accessors.swift

+16
Original file line numberDiff line numberDiff line change
@@ -690,3 +690,19 @@ do {
690690
_ = Test2(q: "some question") // Ok `a` is default initialized to `nil`
691691
_ = Test2(q: "ultimate question", a: 42)
692692
}
693+
694+
struct Test2ForExtension {
695+
var _x: Int
696+
}
697+
698+
extension Test2ForExtension {
699+
var extendedX: Int {
700+
@storageRestrictions(initializes: _x)
701+
init {
702+
// expected-error@-1 {{init accessors cannot be declared in an extension}}
703+
self._x = newValue
704+
}
705+
get { _x }
706+
set { _x = newValue }
707+
}
708+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %s -verify -O -primary-file %s %S/Inputs/imported_init_accessor.swift -c -o %t/init_accessors_multi_file.o
3+
4+
extension S {
5+
init(extendedX: Int) {
6+
self.xImmutablePublic = extendedX
7+
}
8+
}
9+
10+
func test() {
11+
let s = S(extendedX: 42)
12+
_ = s.xImmutablePublic
13+
}

0 commit comments

Comments
 (0)