diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp index c7460c9f31e..7cb992ea474 100644 --- a/lib/AST/Attr.cpp +++ b/lib/AST/Attr.cpp @@ -3172,7 +3172,7 @@ bool CustomAttr::shouldPreferPropertyWrapperOverMacro() const { // if one exists. This is necessary since we don't properly support peer // declarations in local contexts, so want to use a property wrapper if one // exists. - if (auto *D = owner.getAsDecl()) { + if (auto *D = getOwner().getAsDecl()) { if ((isa(D) || isa(D)) && D->getDeclContext()->isLocalContext()) { return true; diff --git a/lib/Sema/TypeCheckMacros.cpp b/lib/Sema/TypeCheckMacros.cpp index 9e57b5a012a..16a91928898 100644 --- a/lib/Sema/TypeCheckMacros.cpp +++ b/lib/Sema/TypeCheckMacros.cpp @@ -2242,8 +2242,12 @@ ResolveMacroRequest::evaluate(Evaluator &evaluator, // So bail out to prevent diagnostics from the contraint system. if (auto *attr = macroRef.getAttr()) { // If we already resolved this CustomAttr to a nominal, this isn't for a - // macro. - if (attr->getNominalDecl()) + // macro. This can only currently be the case for property wrappers, so + // limit the check here to avoid request cycles for member attribute macros + // in cases where the attribute refers to a nested type in the type it's + // attached to, since the qualified lookup there needs to expand member + // attributes. + if (attr->shouldPreferPropertyWrapperOverMacro() && attr->getNominalDecl()) return ConcreteDeclRef(); auto foundMacros = namelookup::lookupMacros(dc, macroRef.getModuleName(), diff --git a/test/NameLookup/rdar163961797.swift b/test/NameLookup/rdar163961797.swift new file mode 100644 index 00000000000..2fc490d21e1 --- /dev/null +++ b/test/NameLookup/rdar163961797.swift @@ -0,0 +1,10 @@ +// RUN: %target-typecheck-verify-swift + +// Make sure we don't end up with a request cycle here, since looking up 'S.Actor' +// requires expanding member attribute macros for 'S'. +@S.Actor +struct S { + @globalActor actor Actor: GlobalActor { + public static let shared = S.Actor() + } +}