Skip to content

Commit fb15b6f

Browse files
committed
[Sema] InitAccessors: Mark properties with init accessor as computed
1 parent 78aee95 commit fb15b6f

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

lib/Sema/TypeCheckStorage.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3497,6 +3497,7 @@ StorageImplInfoRequest::evaluate(Evaluator &evaluator,
34973497
bool hasSetter = storage->getParsedAccessor(AccessorKind::Set);
34983498
bool hasModify = storage->getParsedAccessor(AccessorKind::Modify);
34993499
bool hasMutableAddress = storage->getParsedAccessor(AccessorKind::MutableAddress);
3500+
bool hasInit = storage->getParsedAccessor(AccessorKind::Init);
35003501

35013502
auto *DC = storage->getDeclContext();
35023503
// 'get', 'read', and a non-mutable addressor are all exclusive.
@@ -3510,7 +3511,7 @@ StorageImplInfoRequest::evaluate(Evaluator &evaluator,
35103511

35113512
// If there's a writing accessor of any sort, there must also be a
35123513
// reading accessor.
3513-
} else if (hasSetter || hasModify || hasMutableAddress) {
3514+
} else if (hasInit || hasSetter || hasModify || hasMutableAddress) {
35143515
readImpl = ReadImplKind::Get;
35153516

35163517
// Subscripts always have to have some sort of accessor; they can't be

test/SILOptimizer/init_accessor_definite_init_diagnostics.swift

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,29 @@ struct Test1 {
2020
init(initialValue) initializes(y) {
2121
self.y = initialValue // Ok
2222
}
23+
24+
get { y }
25+
set {}
2326
}
2427

2528
var errorPoint1: (Int, Int) {
2629
init(initialValue) initializes(x y) {
2730
// expected-error@-1 {{property 'x' not initialized by init accessor}}
2831
// expected-error@-2 {{property 'y' not initialized by init accessor}}
2932
}
33+
34+
get { (x, y) }
35+
set { }
3036
}
3137

3238
var errorPoint2: (Int, Int) {
3339
init(initialValue) initializes(x y) {
3440
// expected-error@-1 {{property 'y' not initialized by init accessor}}
3541
self.x = initialValue.0
3642
}
43+
44+
get { (x, y) }
45+
set { }
3746
}
3847

3948
var errorPoint3: (Int, Int) {
@@ -42,6 +51,15 @@ struct Test1 {
4251
print(y) // Ok
4352
print(x) // expected-error {{variable 'x' used before being initialized}}
4453
}
54+
55+
get { (x, y) }
56+
set { }
57+
}
58+
59+
init(x: Int, y: Int) {
60+
self.x = x
61+
self.y = y
62+
self.full = (x, y)
4563
}
4664
}
4765

@@ -79,21 +97,27 @@ struct TestDoubleInit1 {
7997
self.x = initialValue
8098
self.x = 42 // expected-error {{immutable value 'x' may only be initialized once}}
8199
}
100+
101+
get { x }
102+
set { }
82103
}
83104
}
84105

85106
struct TestDoubleInit2 {
86-
let x: Int
107+
let x: Int // expected-note {{change 'let' to 'var' to make it mutable}}
87108

88109
var pointX: Int {
89110
init(initialValue) initializes(x) {
90111
self.x = initialValue
91112
}
113+
114+
get { x }
115+
set { }
92116
}
93117

94118
init(x: Int) {
95119
self.pointX = x
96-
self.x = 0 // FIXME: should be an error because `x` is a `let` property
120+
self.x = 0 // expected-error {{immutable value 'self.x' may only be initialized once}}
97121
}
98122
}
99123

0 commit comments

Comments
 (0)