@@ -543,8 +543,8 @@ static Identifier makeIdentifier(ASTContext &ctx, std::nullptr_t) {
543543 return Identifier ();
544544}
545545
546- bool swift::diagnoseInvalidAttachedMacro (MacroRole role,
547- Decl *attachedTo) {
546+ bool swift::isInvalidAttachedMacro (MacroRole role,
547+ Decl *attachedTo) {
548548 switch (role) {
549549 case MacroRole::Expression:
550550 case MacroRole::Declaration:
@@ -582,9 +582,6 @@ bool swift::diagnoseInvalidAttachedMacro(MacroRole role,
582582 break ;
583583 }
584584
585- attachedTo->diagnose (diag::macro_attached_to_invalid_decl,
586- getMacroRoleString (role),
587- attachedTo->getDescriptiveKind ());
588585 return true ;
589586}
590587
@@ -1362,7 +1359,9 @@ bool swift::accessorMacroOnlyIntroducesObservers(
13621359 for (auto name : attr->getNames ()) {
13631360 if (name.getKind () == MacroIntroducedDeclNameKind::Named &&
13641361 (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)) {
13661365 foundObserver = true ;
13671366 } else {
13681367 // Introduces something other than an observer.
@@ -1413,24 +1412,28 @@ llvm::Optional<unsigned> swift::expandAccessors(AbstractStorageDecl *storage,
14131412 // Trigger parsing of the sequence of accessor declarations. This has the
14141413 // side effect of registering those accessor declarations with the storage
14151414 // 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 ;
14191418 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+ }
14221424
14231425 if (!accessor->isObservingAccessor ()) {
1424- foundNonObservingAccessor = true ;
1426+ if (!foundNonObservingAccessor)
1427+ foundNonObservingAccessor = accessor;
14251428
1426- if (accessor->isInMacroExpansionInContext ())
1427- foundNonObservingAccessorInMacro = true ;
1429+ if (!foundNonObservingAccessorInMacro &&
1430+ accessor->isInMacroExpansionInContext ())
1431+ foundNonObservingAccessorInMacro = accessor;
14281432 }
14291433 }
14301434
14311435 auto roleAttr = macro->getMacroRoleAttr (MacroRole::Accessor);
1432- bool expectedNonObservingAccessor =
1433- !accessorMacroOnlyIntroducesObservers (macro, roleAttr);
1436+ bool expectObservers = accessorMacroOnlyIntroducesObservers (macro, roleAttr);
14341437 if (foundNonObservingAccessorInMacro) {
14351438 // If any non-observing accessor was added, mark the initializer as
14361439 // subsumed unless it has init accessor, because the initializer in
@@ -1451,11 +1454,24 @@ llvm::Optional<unsigned> swift::expandAccessors(AbstractStorageDecl *storage,
14511454 storage->removeAccessor (accessor);
14521455 }
14531456
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) {
14561472 storage->diagnose (
1457- diag::macro_accessor_missing_from_expansion, macro-> getName () ,
1458- !expectedNonObservingAccessor );
1473+ diag::macro_nonobserving_accessor_missing_from_expansion ,
1474+ macro-> getName () );
14591475 }
14601476
14611477 // 'init' accessors must be documented in the macro role attribute.
0 commit comments