Skip to content

Commit 5441539

Browse files
committed
[NFC] Sema: Extracted diagnostic method.
In preparation to introduce more calls.
1 parent a215d72 commit 5441539

File tree

2 files changed

+290
-22
lines changed

2 files changed

+290
-22
lines changed

lib/Sema/TypeCheckStorage.cpp

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,37 @@ IsGetterMutatingRequest::evaluate(Evaluator &evaluator,
683683
llvm_unreachable("bad impl kind");
684684
}
685685

686+
/// As a special extra check, if the user also gave us a modify coroutine,
687+
/// check that it has the same mutatingness as the setter.
688+
/// TODO: arguably this should require the spelling to match even when it's
689+
/// the implied value.
690+
static void diagnoseReadWriteMutatingnessMismatch(
691+
AbstractStorageDecl *storage, bool isWriterMutating, WriteImplKind write,
692+
AccessorKind writeAccesor, ReadWriteImplKind readWrite,
693+
AccessorKind readWriteAccessor) {
694+
if (storage->getImplInfo().getReadWriteImpl() != readWrite)
695+
return;
696+
auto modifyAccessor = storage->getParsedAccessor(readWriteAccessor);
697+
if (!modifyAccessor)
698+
return;
699+
700+
auto isModifierMutating = modifyAccessor->isMutating();
701+
auto isReaderOrWriterMutating =
702+
isWriterMutating || storage->isGetterMutating();
703+
if (isReaderOrWriterMutating == isModifierMutating)
704+
return;
705+
706+
modifyAccessor->diagnose(diag::modify_mutatingness_differs_from_setter,
707+
isModifierMutating ? SelfAccessKind::Mutating
708+
: SelfAccessKind::NonMutating,
709+
isModifierMutating ? SelfAccessKind::NonMutating
710+
: SelfAccessKind::Mutating);
711+
auto *setter = storage->getParsedAccessor(writeAccesor);
712+
if (setter)
713+
setter->diagnose(diag::previous_accessor, "setter", 0);
714+
modifyAccessor->setInvalid();
715+
}
716+
686717
bool
687718
IsSetterMutatingRequest::evaluate(Evaluator &evaluator,
688719
AbstractStorageDecl *storage) const {
@@ -727,28 +758,9 @@ IsSetterMutatingRequest::evaluate(Evaluator &evaluator,
727758
if (setter)
728759
result = setter->isMutating();
729760

730-
731-
// As a special extra check, if the user also gave us a modify
732-
// coroutine, check that it has the same mutatingness as the setter.
733-
// TODO: arguably this should require the spelling to match even when
734-
// it's the implied value.
735-
auto modifyAccessor = storage->getParsedAccessor(AccessorKind::Modify);
736-
737-
if (impl.getReadWriteImpl() == ReadWriteImplKind::Modify &&
738-
modifyAccessor != nullptr) {
739-
auto modifyResult = modifyAccessor->isMutating();
740-
if ((result || storage->isGetterMutating()) != modifyResult) {
741-
modifyAccessor->diagnose(
742-
diag::modify_mutatingness_differs_from_setter,
743-
modifyResult ? SelfAccessKind::Mutating
744-
: SelfAccessKind::NonMutating,
745-
modifyResult ? SelfAccessKind::NonMutating
746-
: SelfAccessKind::Mutating);
747-
if (setter)
748-
setter->diagnose(diag::previous_accessor, "setter", 0);
749-
modifyAccessor->setInvalid();
750-
}
751-
}
761+
diagnoseReadWriteMutatingnessMismatch(
762+
storage, result, WriteImplKind::Set, AccessorKind::Set,
763+
ReadWriteImplKind::Modify, AccessorKind::Modify);
752764

753765
return result;
754766
}

test/Sema/coroutine_accessors.swift

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
// RUN: %target-typecheck-verify-swift \
2+
// RUN: -verify-additional-prefix enabled- \
3+
// RUN: -enable-experimental-feature CoroutineAccessors \
4+
// RUN: -debug-diagnostic-names
5+
6+
7+
struct S {
8+
var i: Int
9+
10+
// Get+Set+_Modify
11+
12+
// +---+---+---+
13+
// | g | s |_m |
14+
// +---+---+---+
15+
// | n | n | n | ok ( ingnsn_m )
16+
// | y | n | n | bad ( ignsn_m )
17+
// | n | y | n | bad ( ingsn_m )
18+
// | y | y | n | bad ( igsn_m )
19+
// | n | n | y | bad ( ingns_m )
20+
// | y | n | y | ok ( igns_m )
21+
// | n | y | y | ok ( ings_m )
22+
// | y | y | y | ok ( igs_m )
23+
// +---+---+---+
24+
25+
var ingnsn_m: Int {
26+
get { 0 }
27+
nonmutating set {}
28+
nonmutating _modify {
29+
var fake: Int
30+
yield &fake
31+
}
32+
}
33+
var ignsn_m: Int {
34+
mutating get { 0 }
35+
nonmutating set {}
36+
// FIXME: Bad diagnostic! The writer is non-mutating--the reader is mutating.
37+
nonmutating _modify { // expected-error{{'modify' accessor cannot be 'nonmutating' when the setter is 'mutating'}}
38+
// expected-note@-3{{setter defined here}}
39+
var fake: Int
40+
yield &fake
41+
}
42+
}
43+
var ingsn_m: Int {
44+
get { 0 }
45+
set {}
46+
nonmutating _modify { // expected-error{{'modify' accessor cannot be 'nonmutating' when the setter is 'mutating'}}
47+
// expected-note@-2{{setter defined here}}
48+
var fake: Int
49+
yield &fake
50+
}
51+
}
52+
var igsn_m: Int {
53+
mutating get { 0 }
54+
set {}
55+
// TODO: Incomplete diagnostic! Both the writer AND the reader are mutating.
56+
nonmutating _modify { // expected-error{{'modify' accessor cannot be 'nonmutating' when the setter is 'mutating'}}
57+
// expected-note@-3{{setter defined here}}
58+
var fake: Int
59+
yield &fake
60+
}
61+
}
62+
var ingns_m: Int {
63+
get { 0 }
64+
nonmutating set {}
65+
_modify { // expected-error{{'modify' accessor cannot be 'mutating' when the setter is 'nonmutating'}}
66+
// expected-note@-2{{setter defined here}}
67+
yield &i
68+
}
69+
}
70+
var igns_m: Int {
71+
mutating get { 0 }
72+
nonmutating set {}
73+
_modify {
74+
yield &i
75+
}
76+
}
77+
var ings_m: Int {
78+
get { 0 }
79+
set {}
80+
_modify {
81+
yield &i
82+
}
83+
}
84+
var igs_m: Int {
85+
mutating get { 0 }
86+
nonmutating set {}
87+
_modify {
88+
yield &i
89+
}
90+
}
91+
92+
// _Read+Set+_Modify
93+
94+
// +---+---+---+
95+
// | _r | s |_m |
96+
// +---+---+---+
97+
// | n | n | n | ok ( in_rnsn_m )
98+
// | y | n | n | bad ( i_rnsn_m )
99+
// | n | y | n | bad ( in_rsn_m )
100+
// | y | y | n | bad ( i_rsn_m )
101+
// | n | n | y | bad ( in_rns_m )
102+
// | y | n | y | ok ( i_rns_m )
103+
// | n | y | y | ok ( in_rs_m )
104+
// | y | y | y | ok ( i_rs_m )
105+
// +---+---+---+
106+
107+
var in_rnsn_m: Int {
108+
_read { yield i }
109+
nonmutating set {}
110+
nonmutating _modify {
111+
var fake: Int
112+
yield &fake
113+
}
114+
}
115+
var i_rnsn_m: Int {
116+
mutating _read { yield i }
117+
nonmutating set {}
118+
// FIXME: Bad diagnostic! The writer is non-mutating--the reader is mutating.
119+
nonmutating _modify { // expected-error{{'modify' accessor cannot be 'nonmutating' when the setter is 'mutating'}}
120+
// expected-note@-3{{setter defined here}}
121+
var fake: Int
122+
yield &fake
123+
}
124+
}
125+
var in_rsn_m: Int {
126+
_read { yield i }
127+
set {}
128+
nonmutating _modify { // expected-error{{'modify' accessor cannot be 'nonmutating' when the setter is 'mutating'}}
129+
// expected-note@-2{{setter defined here}}
130+
var fake: Int
131+
yield &fake
132+
}
133+
}
134+
var i_rsn_m: Int {
135+
mutating _read { yield i }
136+
set {}
137+
// TODO: Incomplete diagnostic! Both the writer AND the reader are mutating.
138+
nonmutating _modify { // expected-error{{'modify' accessor cannot be 'nonmutating' when the setter is 'mutating'}}
139+
// expected-note@-3{{setter defined here}}
140+
var fake: Int
141+
yield &fake
142+
}
143+
}
144+
var in_rns_m: Int {
145+
_read { yield i }
146+
nonmutating set {}
147+
_modify { // expected-error{{'modify' accessor cannot be 'mutating' when the setter is 'nonmutating'}}
148+
// expected-note@-2{{setter defined here}}
149+
yield &i
150+
}
151+
}
152+
var i_rns_m: Int {
153+
mutating _read { yield i }
154+
nonmutating set {}
155+
_modify {
156+
yield &i
157+
}
158+
}
159+
var in_rs_m: Int {
160+
_read { yield i }
161+
set {}
162+
_modify {
163+
yield &i
164+
}
165+
}
166+
var i_rs_m: Int {
167+
mutating _read { yield i }
168+
nonmutating set {}
169+
_modify {
170+
yield &i
171+
}
172+
}
173+
174+
// UnsafeAddress+Set+_Modify
175+
176+
// +---+---+---+
177+
// |ua | s |_m |
178+
// +---+---+---+
179+
// | n | n | n | ok ( inuansn_m )
180+
// | y | n | n | bad ( iuansn_m )
181+
// | n | y | n | bad ( inuasn_m )
182+
// | y | y | n | bad ( iuasn_m )
183+
// | n | n | y | bad ( inuans_m )
184+
// | y | n | y | ok ( iuans_m )
185+
// | n | y | y | ok ( inuas_m )
186+
// | y | y | y | ok ( iuas_m )
187+
// +---+---+---+
188+
189+
var inuansn_m: Int {
190+
unsafeAddress { UnsafePointer(bitPattern: 0x0)! }
191+
nonmutating set {}
192+
nonmutating _modify {
193+
var fake: Int
194+
yield &fake
195+
}
196+
}
197+
var iuansn_m: Int {
198+
mutating unsafeAddress { UnsafePointer(bitPattern: 0x0)! }
199+
nonmutating set {}
200+
// FIXME: Bad diagnostic! The writer is non-mutating--the reader is mutating.
201+
nonmutating _modify { // expected-error{{'modify' accessor cannot be 'nonmutating' when the setter is 'mutating'}}
202+
// expected-note@-3{{setter defined here}}
203+
var fake: Int
204+
yield &fake
205+
}
206+
}
207+
var inuasn_m: Int {
208+
unsafeAddress { UnsafePointer(bitPattern: 0x0)! }
209+
set {}
210+
nonmutating _modify { // expected-error{{'modify' accessor cannot be 'nonmutating' when the setter is 'mutating'}}
211+
// expected-note@-2{{setter defined here}}
212+
var fake: Int
213+
yield &fake
214+
}
215+
}
216+
var iuasn_m: Int {
217+
mutating unsafeAddress { UnsafePointer(bitPattern: 0x0)! }
218+
set {}
219+
// TODO: Incomplete diagnostic! Both the writer AND the reader are mutating.
220+
nonmutating _modify { // expected-error{{'modify' accessor cannot be 'nonmutating' when the setter is 'mutating'}}
221+
// expected-note@-3{{setter defined here}}
222+
var fake: Int
223+
yield &fake
224+
}
225+
}
226+
var inuans_m: Int {
227+
unsafeAddress { UnsafePointer(bitPattern: 0x0)! }
228+
nonmutating set {}
229+
_modify { // expected-error{{'modify' accessor cannot be 'mutating' when the setter is 'nonmutating'}}
230+
// expected-note@-2{{setter defined here}}
231+
yield &i
232+
}
233+
}
234+
var iuans_m: Int {
235+
mutating unsafeAddress { UnsafePointer(bitPattern: 0x0)! }
236+
nonmutating set {}
237+
_modify {
238+
yield &i
239+
}
240+
}
241+
var inuas_m: Int {
242+
unsafeAddress { UnsafePointer(bitPattern: 0x0)! }
243+
set {}
244+
_modify {
245+
yield &i
246+
}
247+
}
248+
var iuas_m: Int {
249+
mutating unsafeAddress { UnsafePointer(bitPattern: 0x0)! }
250+
nonmutating set {}
251+
_modify {
252+
yield &i
253+
}
254+
}
255+
256+
}

0 commit comments

Comments
 (0)