Skip to content

Commit 067e4ec

Browse files
authored
Merge pull request #65410 from DougGregor/macro-cycle-break-part-deux
2 parents f5ac037 + 1f6b3f6 commit 067e4ec

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
@@ -7067,6 +7067,28 @@ ERROR(invalid_macro_role_for_macro_syntax,none,
70677067
ERROR(macro_cannot_introduce_names,none,
70687068
"'%0' macros are not allowed to introduce names", (StringRef))
70697069

7070+
ERROR(macro_resolve_circular_reference, none,
7071+
"circular reference resolving %select{freestanding|attached}0 macro %1",
7072+
(bool, DeclName))
7073+
NOTE(macro_resolve_circular_reference_through, none,
7074+
"while resolving %select{freestanding|attached}0 macro %1",
7075+
(bool, DeclName))
7076+
7077+
ERROR(macro_expand_circular_reference, none,
7078+
"circular reference expanding %0 macro %1", (StringRef, DeclName))
7079+
NOTE(macro_expand_circular_reference_through, none,
7080+
"circular reference expanding %0 macro %1", (StringRef, DeclName))
7081+
7082+
ERROR(macro_expand_circular_reference_entity, none,
7083+
"circular reference expanding %0 macros on %1", (StringRef, DeclName))
7084+
NOTE(macro_expand_circular_reference_entity_through, none,
7085+
"circular reference expanding %0 macros on %1", (StringRef, DeclName))
7086+
7087+
ERROR(macro_expand_circular_reference_unnamed, none,
7088+
"circular reference expanding %0 macros", (StringRef))
7089+
NOTE(macro_expand_circular_reference_unnamed_through, none,
7090+
"circular reference expanding %0 macros", (StringRef))
7091+
70707092
//------------------------------------------------------------------------------
70717093
// MARK: Move Only Errors
70727094
//------------------------------------------------------------------------------

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
/// Represent a loaded plugin either an in-process library or an executable.
@@ -4050,6 +4069,8 @@ class ExpandPeerMacroRequest
40504069

40514070
public:
40524071
bool isCached() const { return true; }
4072+
void diagnoseCycle(DiagnosticEngine &diags) const;
4073+
void noteCycleStep(DiagnosticEngine &diags) const;
40534074
};
40544075

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

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
@@ -462,7 +462,7 @@ ArrayRef<unsigned> ExpandMemberAttributeMacros::evaluate(Evaluator &evaluator,
462462
return { };
463463

464464
auto *parentDecl = decl->getDeclContext()->getAsDecl();
465-
if (!parentDecl)
465+
if (!parentDecl || !isa<IterableDeclContext>(parentDecl))
466466
return { };
467467

468468
if (isa<PatternBindingDecl>(decl))
@@ -1467,7 +1467,9 @@ swift::expandConformances(CustomAttr *attr, MacroDecl *macro,
14671467
ConcreteDeclRef
14681468
ResolveMacroRequest::evaluate(Evaluator &evaluator,
14691469
UnresolvedMacroReference macroRef,
1470-
DeclContext *dc) const {
1470+
const Decl *decl) const {
1471+
auto dc = decl->getDeclContext();
1472+
14711473
// Macro expressions and declarations have their own stored macro
14721474
// reference. Use it if it's there.
14731475
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
@@ -149,9 +149,8 @@ struct S2 {
149149
}
150150

151151
#if TEST_DIAGNOSTICS
152-
// FIXME: Causes reference cycles
153-
// should have error {{cannot find 'nonexistent' in scope}}
154-
// @addCompletionHandlerArbitrarily(nonexistent)
152+
// expected-error@+1 {{cannot find 'nonexistent' in scope}}
153+
@addCompletionHandlerArbitrarily(nonexistent)
155154
func h(a: Int, for b: String, _ value: Double) async -> String {
156155
return b
157156
}

0 commit comments

Comments
 (0)