Skip to content

Commit a4834b3

Browse files
authored
Merge pull request #65411 from DougGregor/macro-cycle-break-part-deux-5.9
[5.9] Improve breaking of cyclic references for member-attribute macros
2 parents e7a2408 + 6028ff1 commit a4834b3

File tree

8 files changed

+207
-10
lines changed

8 files changed

+207
-10
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7059,6 +7059,28 @@ ERROR(invalid_macro_role_for_macro_syntax,none,
70597059
ERROR(macro_cannot_introduce_names,none,
70607060
"'%0' macros are not allowed to introduce names", (StringRef))
70617061

7062+
ERROR(macro_resolve_circular_reference, none,
7063+
"circular reference resolving %select{freestanding|attached}0 macro %1",
7064+
(bool, DeclName))
7065+
NOTE(macro_resolve_circular_reference_through, none,
7066+
"while resolving %select{freestanding|attached}0 macro %1",
7067+
(bool, DeclName))
7068+
7069+
ERROR(macro_expand_circular_reference, none,
7070+
"circular reference expanding %0 macro %1", (StringRef, DeclName))
7071+
NOTE(macro_expand_circular_reference_through, none,
7072+
"circular reference expanding %0 macro %1", (StringRef, DeclName))
7073+
7074+
ERROR(macro_expand_circular_reference_entity, none,
7075+
"circular reference expanding %0 macros on %1", (StringRef, DeclName))
7076+
NOTE(macro_expand_circular_reference_entity_through, none,
7077+
"circular reference expanding %0 macros on %1", (StringRef, DeclName))
7078+
7079+
ERROR(macro_expand_circular_reference_unnamed, none,
7080+
"circular reference expanding %0 macros", (StringRef))
7081+
NOTE(macro_expand_circular_reference_unnamed_through, none,
7082+
"circular reference expanding %0 macros", (StringRef))
7083+
70627084
//------------------------------------------------------------------------------
70637085
// MARK: Move Only Errors
70647086
//------------------------------------------------------------------------------

include/swift/AST/TypeCheckRequests.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3243,6 +3243,12 @@ class UnresolvedMacroReference {
32433243
friend llvm::hash_code hash_value(const UnresolvedMacroReference &ref) {
32443244
return reinterpret_cast<ptrdiff_t>(ref.pointer.getOpaqueValue());
32453245
}
3246+
3247+
friend SourceLoc extractNearestSourceLoc(
3248+
const UnresolvedMacroReference &ref
3249+
) {
3250+
return ref.getSigilLoc();
3251+
}
32463252
};
32473253

32483254
void simple_display(llvm::raw_ostream &out,
@@ -3252,7 +3258,7 @@ void simple_display(llvm::raw_ostream &out,
32523258
class ResolveMacroRequest
32533259
: public SimpleRequest<ResolveMacroRequest,
32543260
ConcreteDeclRef(UnresolvedMacroReference,
3255-
DeclContext *),
3261+
const Decl *),
32563262
RequestFlags::Cached> {
32573263
public:
32583264
using SimpleRequest::SimpleRequest;
@@ -3262,10 +3268,13 @@ class ResolveMacroRequest
32623268

32633269
ConcreteDeclRef
32643270
evaluate(Evaluator &evaluator, UnresolvedMacroReference macroRef,
3265-
DeclContext *dc) const;
3271+
const Decl *decl) const;
32663272

32673273
public:
32683274
bool isCached() const { return true; }
3275+
3276+
void diagnoseCycle(DiagnosticEngine &diags) const;
3277+
void noteCycleStep(DiagnosticEngine &diags) const;
32693278
};
32703279

32713280
class ResolveTypeEraserTypeRequest
@@ -3917,6 +3926,8 @@ class ExpandMacroExpansionDeclRequest
39173926

39183927
public:
39193928
bool isCached() const { return true; }
3929+
void diagnoseCycle(DiagnosticEngine &diags) const;
3930+
void noteCycleStep(DiagnosticEngine &diags) const;
39203931
};
39213932

39223933
/// Expand all accessor macros attached to the given declaration.
@@ -3937,6 +3948,8 @@ class ExpandAccessorMacros
39373948

39383949
public:
39393950
bool isCached() const { return true; }
3951+
void diagnoseCycle(DiagnosticEngine &diags) const;
3952+
void noteCycleStep(DiagnosticEngine &diags) const;
39403953
};
39413954

39423955
/// Expand all conformance macros attached to the given declaration.
@@ -3957,6 +3970,8 @@ class ExpandConformanceMacros
39573970

39583971
public:
39593972
bool isCached() const { return true; }
3973+
void diagnoseCycle(DiagnosticEngine &diags) const;
3974+
void noteCycleStep(DiagnosticEngine &diags) const;
39603975
};
39613976

39623977
/// Expand all member attribute macros attached to the given
@@ -3977,6 +3992,8 @@ class ExpandMemberAttributeMacros
39773992

39783993
public:
39793994
bool isCached() const { return true; }
3995+
void diagnoseCycle(DiagnosticEngine &diags) const;
3996+
void noteCycleStep(DiagnosticEngine &diags) const;
39803997
};
39813998

39823999
/// Expand synthesized member macros attached to the given declaration.
@@ -3996,6 +4013,8 @@ class ExpandSynthesizedMemberMacroRequest
39964013

39974014
public:
39984015
bool isCached() const { return true; }
4016+
void diagnoseCycle(DiagnosticEngine &diags) const;
4017+
void noteCycleStep(DiagnosticEngine &diags) const;
39994018
};
40004019

40014020
/// Load a plugin module with the given name.
@@ -4069,6 +4088,8 @@ class ExpandPeerMacroRequest
40694088

40704089
public:
40714090
bool isCached() const { return true; }
4091+
void diagnoseCycle(DiagnosticEngine &diags) const;
4092+
void noteCycleStep(DiagnosticEngine &diags) const;
40724093
};
40734094

40744095
/// Resolve an external macro given its module and type name.

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ SWIFT_REQUEST(TypeChecker, ResolveImplicitMemberRequest,
349349
evaluator::SideEffect(NominalTypeDecl *, ImplicitMemberAction),
350350
Uncached, NoLocationInfo)
351351
SWIFT_REQUEST(TypeChecker, ResolveMacroRequest,
352-
ConcreteDeclRef(UnresolvedMacroReference, DeclContext *),
352+
ConcreteDeclRef(UnresolvedMacroReference, const Decl *),
353353
Cached, NoLocationInfo)
354354
SWIFT_REQUEST(TypeChecker, ResolveTypeEraserTypeRequest,
355355
Type(ProtocolDecl *, TypeEraserAttr *),

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ void Decl::forEachAttachedMacro(MacroRole role,
445445
MacroDecl *Decl::getResolvedMacro(CustomAttr *customAttr) const {
446446
auto declRef = evaluateOrDefault(
447447
getASTContext().evaluator,
448-
ResolveMacroRequest{customAttr, getDeclContext()},
448+
ResolveMacroRequest{customAttr, this},
449449
ConcreteDeclRef());
450450

451451
return dyn_cast_or_null<MacroDecl>(declRef.getDecl());

lib/AST/TypeCheckRequests.cpp

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,3 +1792,156 @@ bool swift::operator==(MacroRoles lhs, MacroRoles rhs) {
17921792
llvm::hash_code swift::hash_value(MacroRoles roles) {
17931793
return roles.toRaw();
17941794
}
1795+
1796+
static bool isAttachedSyntax(const UnresolvedMacroReference &ref) {
1797+
return ref.getAttr() != nullptr;
1798+
}
1799+
1800+
void ResolveMacroRequest::diagnoseCycle(DiagnosticEngine &diags) const {
1801+
const auto &storage = getStorage();
1802+
auto macroRef = std::get<0>(storage);
1803+
diags.diagnose(macroRef.getSigilLoc(), diag::macro_resolve_circular_reference,
1804+
isAttachedSyntax(macroRef),
1805+
macroRef.getMacroName().getFullName());
1806+
}
1807+
1808+
void ResolveMacroRequest::noteCycleStep(DiagnosticEngine &diags) const {
1809+
const auto &storage = getStorage();
1810+
auto macroRef = std::get<0>(storage);
1811+
diags.diagnose(macroRef.getSigilLoc(),
1812+
diag::macro_resolve_circular_reference_through,
1813+
isAttachedSyntax(macroRef),
1814+
macroRef.getMacroName().getFullName());
1815+
}
1816+
1817+
void ExpandMacroExpansionDeclRequest::diagnoseCycle(DiagnosticEngine &diags) const {
1818+
auto decl = std::get<0>(getStorage());
1819+
diags.diagnose(decl->getPoundLoc(),
1820+
diag::macro_expand_circular_reference,
1821+
"freestanding",
1822+
decl->getMacroName().getFullName());
1823+
}
1824+
1825+
void ExpandMacroExpansionDeclRequest::noteCycleStep(DiagnosticEngine &diags) const {
1826+
auto decl = std::get<0>(getStorage());
1827+
diags.diagnose(decl->getPoundLoc(),
1828+
diag::macro_expand_circular_reference_through,
1829+
"freestanding",
1830+
decl->getMacroName().getFullName());
1831+
}
1832+
1833+
void ExpandAccessorMacros::diagnoseCycle(DiagnosticEngine &diags) const {
1834+
auto decl = std::get<0>(getStorage());
1835+
diags.diagnose(decl->getLoc(),
1836+
diag::macro_expand_circular_reference_entity,
1837+
"accessor",
1838+
decl->getName());
1839+
}
1840+
1841+
void ExpandAccessorMacros::noteCycleStep(DiagnosticEngine &diags) const {
1842+
auto decl = std::get<0>(getStorage());
1843+
diags.diagnose(decl->getLoc(),
1844+
diag::macro_expand_circular_reference_entity_through,
1845+
"accessor",
1846+
decl->getName());
1847+
}
1848+
1849+
void ExpandConformanceMacros::diagnoseCycle(DiagnosticEngine &diags) const {
1850+
auto decl = std::get<0>(getStorage());
1851+
diags.diagnose(decl->getLoc(),
1852+
diag::macro_expand_circular_reference_entity,
1853+
"conformance",
1854+
decl->getName());
1855+
}
1856+
1857+
void ExpandConformanceMacros::noteCycleStep(DiagnosticEngine &diags) const {
1858+
auto decl = std::get<0>(getStorage());
1859+
diags.diagnose(decl->getLoc(),
1860+
diag::macro_expand_circular_reference_entity_through,
1861+
"conformance",
1862+
decl->getName());
1863+
}
1864+
1865+
void ExpandMemberAttributeMacros::diagnoseCycle(DiagnosticEngine &diags) const {
1866+
auto decl = std::get<0>(getStorage());
1867+
if (auto value = dyn_cast<ValueDecl>(decl)) {
1868+
diags.diagnose(decl->getLoc(),
1869+
diag::macro_expand_circular_reference_entity,
1870+
"member attribute",
1871+
value->getName());
1872+
} else {
1873+
diags.diagnose(decl->getLoc(),
1874+
diag::macro_expand_circular_reference_unnamed,
1875+
"member attribute");
1876+
}
1877+
}
1878+
1879+
void ExpandMemberAttributeMacros::noteCycleStep(DiagnosticEngine &diags) const {
1880+
auto decl = std::get<0>(getStorage());
1881+
if (auto value = dyn_cast<ValueDecl>(decl)) {
1882+
diags.diagnose(decl->getLoc(),
1883+
diag::macro_expand_circular_reference_entity_through,
1884+
"member attribute",
1885+
value->getName());
1886+
} else {
1887+
diags.diagnose(decl->getLoc(),
1888+
diag::macro_expand_circular_reference_unnamed_through,
1889+
"member attribute");
1890+
}
1891+
}
1892+
1893+
void ExpandSynthesizedMemberMacroRequest::diagnoseCycle(DiagnosticEngine &diags) const {
1894+
auto decl = std::get<0>(getStorage());
1895+
if (auto value = dyn_cast<ValueDecl>(decl)) {
1896+
diags.diagnose(decl->getLoc(),
1897+
diag::macro_expand_circular_reference_entity,
1898+
"member",
1899+
value->getName());
1900+
} else {
1901+
diags.diagnose(decl->getLoc(),
1902+
diag::macro_expand_circular_reference_unnamed,
1903+
"member");
1904+
}
1905+
}
1906+
1907+
void ExpandSynthesizedMemberMacroRequest::noteCycleStep(DiagnosticEngine &diags) const {
1908+
auto decl = std::get<0>(getStorage());
1909+
if (auto value = dyn_cast<ValueDecl>(decl)) {
1910+
diags.diagnose(decl->getLoc(),
1911+
diag::macro_expand_circular_reference_entity_through,
1912+
"member",
1913+
value->getName());
1914+
} else {
1915+
diags.diagnose(decl->getLoc(),
1916+
diag::macro_expand_circular_reference_unnamed_through,
1917+
"member");
1918+
}
1919+
}
1920+
1921+
void ExpandPeerMacroRequest::diagnoseCycle(DiagnosticEngine &diags) const {
1922+
auto decl = std::get<0>(getStorage());
1923+
if (auto value = dyn_cast<ValueDecl>(decl)) {
1924+
diags.diagnose(decl->getLoc(),
1925+
diag::macro_expand_circular_reference_entity,
1926+
"peer",
1927+
value->getName());
1928+
} else {
1929+
diags.diagnose(decl->getLoc(),
1930+
diag::macro_expand_circular_reference_unnamed,
1931+
"peer");
1932+
}
1933+
}
1934+
1935+
void ExpandPeerMacroRequest::noteCycleStep(DiagnosticEngine &diags) const {
1936+
auto decl = std::get<0>(getStorage());
1937+
if (auto value = dyn_cast<ValueDecl>(decl)) {
1938+
diags.diagnose(decl->getLoc(),
1939+
diag::macro_expand_circular_reference_entity_through,
1940+
"peer",
1941+
value->getName());
1942+
} else {
1943+
diags.diagnose(decl->getLoc(),
1944+
diag::macro_expand_circular_reference_unnamed_through,
1945+
"peer");
1946+
}
1947+
}

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3796,7 +3796,7 @@ ExpandMacroExpansionDeclRequest::evaluate(Evaluator &evaluator,
37963796

37973797
// Resolve macro candidates.
37983798
auto macro = evaluateOrDefault(
3799-
ctx.evaluator, ResolveMacroRequest{MED, dc},
3799+
ctx.evaluator, ResolveMacroRequest{MED, MED},
38003800
ConcreteDeclRef());
38013801
if (!macro)
38023802
return None;

lib/Sema/TypeCheckMacros.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ ArrayRef<unsigned> ExpandMemberAttributeMacros::evaluate(Evaluator &evaluator,
474474
return { };
475475

476476
auto *parentDecl = decl->getDeclContext()->getAsDecl();
477-
if (!parentDecl)
477+
if (!parentDecl || !isa<IterableDeclContext>(parentDecl))
478478
return { };
479479

480480
if (isa<PatternBindingDecl>(decl))
@@ -1491,7 +1491,9 @@ swift::expandConformances(CustomAttr *attr, MacroDecl *macro,
14911491
ConcreteDeclRef
14921492
ResolveMacroRequest::evaluate(Evaluator &evaluator,
14931493
UnresolvedMacroReference macroRef,
1494-
DeclContext *dc) const {
1494+
const Decl *decl) const {
1495+
auto dc = decl->getDeclContext();
1496+
14951497
// Macro expressions and declarations have their own stored macro
14961498
// reference. Use it if it's there.
14971499
if (auto *expr = macroRef.getExpr()) {

test/Macros/macro_expand_peers.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,8 @@ struct S2 {
145145
}
146146

147147
#if TEST_DIAGNOSTICS
148-
// FIXME: Causes reference cycles
149-
// should have error {{cannot find 'nonexistent' in scope}}
150-
// @addCompletionHandlerArbitrarily(nonexistent)
148+
// expected-error@+1 {{cannot find 'nonexistent' in scope}}
149+
@addCompletionHandlerArbitrarily(nonexistent)
151150
func h(a: Int, for b: String, _ value: Double) async -> String {
152151
return b
153152
}

0 commit comments

Comments
 (0)