Skip to content

Commit 5abb77d

Browse files
committed
Improve cyclic reference diagnostics for macro resolution and expansion
We are likely to debugging more cyclic references involving macros in the future, so improve the diagnostics to specify what operation we're performing (e.g., macro resolution vs. expansion of a particular kind of macro) and the macro name, when possible, so failures are easier to diagnose. No functionality change for well-formed code.
1 parent 35b784c commit 5abb77d

File tree

3 files changed

+196
-0
lines changed

3 files changed

+196
-0
lines changed

include/swift/AST/DiagnosticsSema.def

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

7057+
ERROR(macro_resolve_circular_reference, none,
7058+
"circular reference resolving %select{freestanding|attached}0 macro %1",
7059+
(bool, DeclName))
7060+
NOTE(macro_resolve_circular_reference_through, none,
7061+
"while resolving %select{freestanding|attached}0 macro %1",
7062+
(bool, DeclName))
7063+
7064+
ERROR(macro_expand_circular_reference, none,
7065+
"circular reference expanding %0 macro %1", (StringRef, DeclName))
7066+
NOTE(macro_expand_circular_reference_through, none,
7067+
"circular reference expanding %0 macro %1", (StringRef, DeclName))
7068+
7069+
ERROR(macro_expand_circular_reference_entity, none,
7070+
"circular reference expanding %0 macros on %1", (StringRef, DeclName))
7071+
NOTE(macro_expand_circular_reference_entity_through, none,
7072+
"circular reference expanding %0 macros on %1", (StringRef, DeclName))
7073+
7074+
ERROR(macro_expand_circular_reference_unnamed, none,
7075+
"circular reference expanding %0 macros", (StringRef))
7076+
NOTE(macro_expand_circular_reference_unnamed_through, none,
7077+
"circular reference expanding %0 macros", (StringRef))
7078+
70577079
//------------------------------------------------------------------------------
70587080
// MARK: Move Only Errors
70597081
//------------------------------------------------------------------------------

include/swift/AST/TypeCheckRequests.h

Lines changed: 21 additions & 0 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,
@@ -3266,6 +3272,9 @@ class ResolveMacroRequest
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.

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+
}

0 commit comments

Comments
 (0)