Skip to content

Commit 3b536c6

Browse files
committed
[Macros] Cope with local types and opaque result types in macros and expansions
Address a few related issues that affect local types and opaque result types within macros: * Don't add local types or opaque types encountered while parsing the arguments of a freestanding macro to the global list. When we do add them, make sure we're adding them to the outermost source file so they'll get seen later. This avoids trying to generate code for these types, because they aren't supposed to be part of the program. Note that a similar problem remains for arguments to attached macros, which will need to be addressed with a more significant refactoring. * When determining whether opaque types should be substituted within a resilience domain, check the outermost source files rather than the exact source file, otherwise we will end up with a mismatch in argument-passing conventions. * When delaying the type checking of functions that occur as part of a macro expansion, make sure we record them in the outermost Swift source file. Otherwise, we won't come back to them. There is a common theme here of using AST state on the source file in a manner that isn't ideal, and starts to break down with macros. In these cases, we're relying on side effects from earlier phases (parsing and type checking) to inform later phases, rather than properly expressing the dependencies through requests. Fixes rdar://110674997&110713264.
1 parent b624759 commit 3b536c6

File tree

6 files changed

+33
-9
lines changed

6 files changed

+33
-9
lines changed

include/swift/Parse/Parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ class Parser {
155155
/// ASTScopes are not created in inactive clauses and lookups to decls will fail.
156156
bool InInactiveClauseEnvironment = false;
157157
bool InSwiftKeyPath = false;
158+
bool InFreestandingMacroArgument = false;
158159

159160
/// Whether we should delay parsing nominal type, extension, and function
160161
/// bodies.

lib/AST/TypeSubstitution.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,8 +1036,8 @@ static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,
10361036

10371037
// In the same file any visibility is okay.
10381038
if (!dc->isModuleContext() &&
1039-
typeDecl->getDeclContext()->getParentSourceFile() ==
1040-
dc->getParentSourceFile())
1039+
typeDecl->getDeclContext()->getOutermostParentSourceFile() ==
1040+
dc->getOutermostParentSourceFile())
10411041
return true;
10421042

10431043
return typeDecl->getEffectiveAccess() > AccessLevel::FilePrivate;

lib/Parse/ParseDecl.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5137,7 +5137,7 @@ void Parser::recordLocalType(TypeDecl *TD) {
51375137
if (!TD->getDeclContext()->isLocalContext())
51385138
return;
51395139

5140-
if (!InInactiveClauseEnvironment)
5140+
if (!InInactiveClauseEnvironment && !InFreestandingMacroArgument)
51415141
SF.getOutermostParentSourceFile()->LocalTypeDecls.insert(TD);
51425142
}
51435143

@@ -7907,7 +7907,7 @@ Parser::parseDeclVar(ParseDeclOptions Flags,
79077907
if (auto typedPattern = dyn_cast<TypedPattern>(pattern)) {
79087908
hasOpaqueReturnTy = typedPattern->getTypeRepr()->hasOpaque();
79097909
}
7910-
auto sf = CurDeclContext->getParentSourceFile();
7910+
auto sf = CurDeclContext->getOutermostParentSourceFile();
79117911

79127912
// Configure all vars with attributes, 'static' and parent pattern.
79137913
pattern->forEachVariable([&](VarDecl *VD) {
@@ -7919,7 +7919,8 @@ Parser::parseDeclVar(ParseDeclOptions Flags,
79197919
setOriginalDeclarationForDifferentiableAttributes(Attributes, VD);
79207920

79217921
Decls.push_back(VD);
7922-
if (hasOpaqueReturnTy && sf && !InInactiveClauseEnvironment) {
7922+
if (hasOpaqueReturnTy && sf && !InInactiveClauseEnvironment
7923+
&& !InFreestandingMacroArgument) {
79237924
sf->addUnvalidatedDeclWithOpaqueResultType(VD);
79247925
}
79257926
});
@@ -8209,8 +8210,8 @@ ParserResult<FuncDecl> Parser::parseDeclFunc(SourceLoc StaticLoc,
82098210

82108211
// Let the source file track the opaque return type mapping, if any.
82118212
if (FuncRetTy && FuncRetTy->hasOpaque() &&
8212-
!InInactiveClauseEnvironment) {
8213-
if (auto sf = CurDeclContext->getParentSourceFile()) {
8213+
!InInactiveClauseEnvironment && !InFreestandingMacroArgument) {
8214+
if (auto sf = CurDeclContext->getOutermostParentSourceFile()) {
82148215
sf->addUnvalidatedDeclWithOpaqueResultType(FD);
82158216
}
82168217
}
@@ -9156,8 +9157,8 @@ Parser::parseDeclSubscript(SourceLoc StaticLoc,
91569157

91579158
// Let the source file track the opaque return type mapping, if any.
91589159
if (ElementTy.get() && ElementTy.get()->hasOpaque() &&
9159-
!InInactiveClauseEnvironment) {
9160-
if (auto sf = CurDeclContext->getParentSourceFile()) {
9160+
!InInactiveClauseEnvironment && !InFreestandingMacroArgument) {
9161+
if (auto sf = CurDeclContext->getOutermostParentSourceFile()) {
91619162
sf->addUnvalidatedDeclWithOpaqueResultType(Subscript);
91629163
}
91639164
}

lib/Parse/ParseExpr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2337,6 +2337,8 @@ ParserStatus Parser::parseFreestandingMacroExpansion(
23372337
diagnose(leftAngleLoc, diag::while_parsing_as_left_angle_bracket);
23382338
}
23392339

2340+
llvm::SaveAndRestore<bool> inMacroArgument(InFreestandingMacroArgument, true);
2341+
23402342
if (Tok.isFollowingLParen()) {
23412343
auto result = parseArgumentList(tok::l_paren, tok::r_paren, isExprBasic,
23422344
/*allowTrailingClosure*/ true);

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,6 +1851,10 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
18511851
ASTContext &getASTContext() const { return Ctx; }
18521852
void addDelayedFunction(AbstractFunctionDecl *AFD) {
18531853
if (!SF) return;
1854+
1855+
while (auto enclosingSF = SF->getEnclosingSourceFile())
1856+
SF = enclosingSF;
1857+
18541858
SF->DelayedFunctions.push_back(AFD);
18551859
}
18561860

test/Macros/macro_expand.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,22 @@ public struct Outer {
197197
// CHECK: (2, "a + b")
198198
testStringify(a: 1, b: 1)
199199

200+
protocol P { }
201+
extension Int: P { }
202+
203+
// Stringify with closures that have local types.
204+
@available(SwiftStdlib 5.1, *)
205+
func testStringifyWithLocalTypes() {
206+
_ = #stringify({
207+
struct LocalType: P {
208+
static var name: String = "Taylor"
209+
var something: some P { self }
210+
}
211+
212+
func f() -> some P { return LocalType().something }
213+
})
214+
}
215+
200216
func maybeThrowing() throws -> Int { 5 }
201217
202218
#if TEST_DIAGNOSTICS

0 commit comments

Comments
 (0)