@@ -543,8 +543,8 @@ static Identifier makeIdentifier(ASTContext &ctx, std::nullptr_t) {
543
543
return Identifier ();
544
544
}
545
545
546
- bool swift::diagnoseInvalidAttachedMacro (MacroRole role,
547
- Decl *attachedTo) {
546
+ bool swift::isInvalidAttachedMacro (MacroRole role,
547
+ Decl *attachedTo) {
548
548
switch (role) {
549
549
case MacroRole::Expression:
550
550
case MacroRole::Declaration:
@@ -582,9 +582,6 @@ bool swift::diagnoseInvalidAttachedMacro(MacroRole role,
582
582
break ;
583
583
}
584
584
585
- attachedTo->diagnose (diag::macro_attached_to_invalid_decl,
586
- getMacroRoleString (role),
587
- attachedTo->getDescriptiveKind ());
588
585
return true ;
589
586
}
590
587
@@ -1362,7 +1359,9 @@ bool swift::accessorMacroOnlyIntroducesObservers(
1362
1359
for (auto name : attr->getNames ()) {
1363
1360
if (name.getKind () == MacroIntroducedDeclNameKind::Named &&
1364
1361
(name.getName ().getBaseName ().userFacingName () == " willSet" ||
1365
- name.getName ().getBaseName ().userFacingName () == " didSet" )) {
1362
+ name.getName ().getBaseName ().userFacingName () == " didSet" ||
1363
+ name.getName ().getBaseName ().getKind () ==
1364
+ DeclBaseName::Kind::Constructor)) {
1366
1365
foundObserver = true ;
1367
1366
} else {
1368
1367
// Introduces something other than an observer.
@@ -1413,24 +1412,28 @@ llvm::Optional<unsigned> swift::expandAccessors(AbstractStorageDecl *storage,
1413
1412
// Trigger parsing of the sequence of accessor declarations. This has the
1414
1413
// side effect of registering those accessor declarations with the storage
1415
1414
// declaration, so there is nothing further to do.
1416
- bool foundNonObservingAccessor = false ;
1417
- bool foundNonObservingAccessorInMacro = false ;
1418
- bool foundInitAccessor = false ;
1415
+ AccessorDecl * foundNonObservingAccessor = nullptr ;
1416
+ AccessorDecl * foundNonObservingAccessorInMacro = nullptr ;
1417
+ AccessorDecl * foundInitAccessor = nullptr ;
1419
1418
for (auto accessor : storage->getAllAccessors ()) {
1420
- if (accessor->isInitAccessor ())
1421
- foundInitAccessor = true ;
1419
+ if (accessor->isInitAccessor ()) {
1420
+ if (!foundInitAccessor)
1421
+ foundInitAccessor = accessor;
1422
+ continue ;
1423
+ }
1422
1424
1423
1425
if (!accessor->isObservingAccessor ()) {
1424
- foundNonObservingAccessor = true ;
1426
+ if (!foundNonObservingAccessor)
1427
+ foundNonObservingAccessor = accessor;
1425
1428
1426
- if (accessor->isInMacroExpansionInContext ())
1427
- foundNonObservingAccessorInMacro = true ;
1429
+ if (!foundNonObservingAccessorInMacro &&
1430
+ accessor->isInMacroExpansionInContext ())
1431
+ foundNonObservingAccessorInMacro = accessor;
1428
1432
}
1429
1433
}
1430
1434
1431
1435
auto roleAttr = macro->getMacroRoleAttr (MacroRole::Accessor);
1432
- bool expectedNonObservingAccessor =
1433
- !accessorMacroOnlyIntroducesObservers (macro, roleAttr);
1436
+ bool expectObservers = accessorMacroOnlyIntroducesObservers (macro, roleAttr);
1434
1437
if (foundNonObservingAccessorInMacro) {
1435
1438
// If any non-observing accessor was added, mark the initializer as
1436
1439
// subsumed unless it has init accessor, because the initializer in
@@ -1451,11 +1454,24 @@ llvm::Optional<unsigned> swift::expandAccessors(AbstractStorageDecl *storage,
1451
1454
storage->removeAccessor (accessor);
1452
1455
}
1453
1456
1454
- // Make sure we got non-observing accessors exactly where we expected to.
1455
- if (foundNonObservingAccessor != expectedNonObservingAccessor) {
1457
+ // If the macro told us to expect only observing accessors, but the macro
1458
+ // produced a non-observing accessor, it could have converted a stored
1459
+ // property into a computed one without telling us pre-expansion. Produce
1460
+ // an error to prevent this.
1461
+ if (expectObservers && foundNonObservingAccessorInMacro) {
1462
+ storage->diagnose (
1463
+ diag::macro_nonobserver_unexpected_in_expansion, macro->getName (),
1464
+ foundNonObservingAccessorInMacro->getDescriptiveKind ());
1465
+ }
1466
+
1467
+ // We expected to get a non-observing accessor, but there isn't one (from
1468
+ // the macro or elsewhere), meaning that we counted on this macro to make
1469
+ // this stored property into a a computed property... but it didn't.
1470
+ // Produce an error.
1471
+ if (!expectObservers && !foundNonObservingAccessor) {
1456
1472
storage->diagnose (
1457
- diag::macro_accessor_missing_from_expansion, macro-> getName () ,
1458
- !expectedNonObservingAccessor );
1473
+ diag::macro_nonobserving_accessor_missing_from_expansion ,
1474
+ macro-> getName () );
1459
1475
}
1460
1476
1461
1477
// 'init' accessors must be documented in the macro role attribute.
0 commit comments