@@ -209,112 +209,6 @@ getTypesToCompare(ValueDecl *reqt, Type reqtType, bool reqtTypeIsIUO,
209
209
return std::make_tuple (reqtType, witnessType, optAdjustment);
210
210
}
211
211
212
- // Verify that the mutating bit is correct between a protocol requirement and a
213
- // witness. This returns true on invalid.
214
- static bool checkMutating (FuncDecl *requirement, FuncDecl *witness,
215
- ValueDecl *witnessDecl) {
216
- // Witnesses in classes never have mutating conflicts.
217
- if (auto contextType =
218
- witnessDecl->getDeclContext ()->getDeclaredInterfaceType ())
219
- if (contextType->hasReferenceSemantics ())
220
- return false ;
221
-
222
- // Determine whether the witness will be mutating or not. If the witness is
223
- // stored property accessor, it may not be synthesized yet.
224
- bool witnessMutating;
225
- if (witness)
226
- witnessMutating = (requirement->isInstanceMember () &&
227
- witness->isMutating ());
228
- else {
229
- auto reqtAsAccessor = cast<AccessorDecl>(requirement);
230
- auto storage = cast<AbstractStorageDecl>(witnessDecl);
231
-
232
- auto isReadMutating = [&] {
233
- switch (storage->getReadImpl ()) {
234
- case ReadImplKind::Stored:
235
- return false ;
236
- case ReadImplKind::Address:
237
- return storage->getAddressor ()->isMutating ();
238
- case ReadImplKind::Read:
239
- return storage->getReadCoroutine ()->isMutating ();
240
- case ReadImplKind::Inherited:
241
- case ReadImplKind::Get:
242
- llvm_unreachable (" should have a getter" );
243
- }
244
- llvm_unreachable (" unhandled kind" );
245
- };
246
-
247
- auto isStoredSetterMutating = [&] {
248
- // A stored property on a value type will have a mutating setter
249
- // and a non-mutating getter.
250
- return reqtAsAccessor->isInstanceMember ();
251
- };
252
-
253
- auto isWriteMutating = [&] {
254
- switch (storage->getWriteImpl ()) {
255
- case WriteImplKind::Stored:
256
- return isStoredSetterMutating ();
257
- case WriteImplKind::MutableAddress:
258
- return storage->getMutableAddressor ()->isMutating ();
259
- case WriteImplKind::Modify:
260
- return storage->getModifyCoroutine ()->isMutating ();
261
- case WriteImplKind::Immutable:
262
- llvm_unreachable (" asking for setter for immutable storage" );
263
- case WriteImplKind::Set:
264
- case WriteImplKind::StoredWithObservers:
265
- case WriteImplKind::InheritedWithObservers:
266
- llvm_unreachable (" should have a setter" );
267
- }
268
- llvm_unreachable (" unhandled kind" );
269
- };
270
-
271
- auto isReadWriteMutating = [&] {
272
- switch (storage->getReadWriteImpl ()) {
273
- case ReadWriteImplKind::Stored:
274
- return isStoredSetterMutating ();
275
- case ReadWriteImplKind::MutableAddress:
276
- return storage->getMutableAddressor ()->isMutating ();
277
- case ReadWriteImplKind::Modify:
278
- return storage->getModifyCoroutine ()->isMutating ();
279
- case ReadWriteImplKind::MaterializeToTemporary:
280
- return isReadMutating () || isWriteMutating ();
281
- case ReadWriteImplKind::Immutable:
282
- llvm_unreachable (" asking for setter for immutable storage" );
283
- }
284
- llvm_unreachable (" unhandled kind" );
285
- };
286
-
287
- switch (reqtAsAccessor->getAccessorKind ()) {
288
- case AccessorKind::Get:
289
- case AccessorKind::Read:
290
- witnessMutating = isReadMutating ();
291
- break ;
292
-
293
- case AccessorKind::Set:
294
- witnessMutating = isWriteMutating ();
295
- break ;
296
-
297
- case AccessorKind::Modify:
298
- witnessMutating = isReadWriteMutating ();
299
- break ;
300
-
301
- #define OPAQUE_ACCESSOR (ID, KEYWORD )
302
- #define ACCESSOR (ID ) \
303
- case AccessorKind::ID:
304
- #include " swift/AST/AccessorKinds.def"
305
- llvm_unreachable (" unexpected accessor requirement" );
306
- }
307
- }
308
-
309
- // Requirements in class-bound protocols never 'mutate' self.
310
- auto *proto = cast<ProtocolDecl>(requirement->getDeclContext ());
311
- bool requirementMutating = (requirement->isMutating () &&
312
- !proto->requiresClass ());
313
-
314
- // The witness must not be more mutating than the requirement.
315
- return !requirementMutating && witnessMutating;
316
- }
317
-
318
212
// / Check that the Objective-C method(s) provided by the witness have
319
213
// / the same selectors as those required by the requirement.
320
214
static bool checkObjCWitnessSelector (TypeChecker &tc, ValueDecl *req,
@@ -484,7 +378,7 @@ swift::matchWitness(
484
378
return RequirementMatch (witness, MatchKind::PostfixNonPostfixConflict);
485
379
486
380
// Check that the mutating bit is ok.
487
- if (checkMutating ( funcReq, funcWitness, funcWitness))
381
+ if (! funcReq-> isMutating () && funcWitness-> isMutating ( ))
488
382
return RequirementMatch (witness, MatchKind::MutatingConflict);
489
383
490
384
// If the requirement is rethrows, the witness must either be
@@ -509,15 +403,15 @@ swift::matchWitness(
509
403
return RequirementMatch (witness, MatchKind::SettableConflict);
510
404
511
405
// Validate that the 'mutating' bit lines up for getters and setters.
512
- if (checkMutating (reqASD->getGetter (), witnessASD->getGetter (),
513
- witnessASD))
406
+ if (!reqASD->isGetterMutating () && witnessASD->isGetterMutating ())
514
407
return RequirementMatch (getStandinForAccessor (witnessASD, AccessorKind::Get),
515
408
MatchKind::MutatingConflict);
516
-
517
- if (req->isSettable (req->getDeclContext ()) &&
518
- checkMutating (reqASD->getSetter (), witnessASD->getSetter (), witnessASD))
519
- return RequirementMatch (getStandinForAccessor (witnessASD, AccessorKind::Set),
520
- MatchKind::MutatingConflict);
409
+
410
+ if (req->isSettable (req->getDeclContext ())) {
411
+ if (!reqASD->isSetterMutating () && witnessASD->isSetterMutating ())
412
+ return RequirementMatch (getStandinForAccessor (witnessASD, AccessorKind::Set),
413
+ MatchKind::MutatingConflict);
414
+ }
521
415
522
416
// Decompose the parameters for subscript declarations.
523
417
decomposeFunctionType = isa<SubscriptDecl>(req);
0 commit comments