Skip to content

Commit 6fca08a

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 6265f0c commit 6fca08a

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
@@ -156,6 +156,7 @@ class Parser {
156156
/// ASTScopes are not created in inactive clauses and lookups to decls will fail.
157157
bool InInactiveClauseEnvironment = false;
158158
bool InSwiftKeyPath = false;
159+
bool InFreestandingMacroArgument = false;
159160

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

lib/AST/TypeSubstitution.cpp

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

10441044
// In the same file any visibility is okay.
10451045
if (!dc->isModuleContext() &&
1046-
typeDecl->getDeclContext()->getParentSourceFile() ==
1047-
dc->getParentSourceFile())
1046+
typeDecl->getDeclContext()->getOutermostParentSourceFile() ==
1047+
dc->getOutermostParentSourceFile())
10481048
return true;
10491049

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

lib/Parse/ParseDecl.cpp

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

5212-
if (!InInactiveClauseEnvironment)
5212+
if (!InInactiveClauseEnvironment && !InFreestandingMacroArgument)
52135213
SF.getOutermostParentSourceFile()->LocalTypeDecls.insert(TD);
52145214
}
52155215

@@ -7980,7 +7980,7 @@ Parser::parseDeclVar(ParseDeclOptions Flags,
79807980
if (auto typedPattern = dyn_cast<TypedPattern>(pattern)) {
79817981
hasOpaqueReturnTy = typedPattern->getTypeRepr()->hasOpaque();
79827982
}
7983-
auto sf = CurDeclContext->getParentSourceFile();
7983+
auto sf = CurDeclContext->getOutermostParentSourceFile();
79847984

79857985
// Configure all vars with attributes, 'static' and parent pattern.
79867986
pattern->forEachVariable([&](VarDecl *VD) {
@@ -7992,7 +7992,8 @@ Parser::parseDeclVar(ParseDeclOptions Flags,
79927992
setOriginalDeclarationForDifferentiableAttributes(Attributes, VD);
79937993

79947994
Decls.push_back(VD);
7995-
if (hasOpaqueReturnTy && sf && !InInactiveClauseEnvironment) {
7995+
if (hasOpaqueReturnTy && sf && !InInactiveClauseEnvironment
7996+
&& !InFreestandingMacroArgument) {
79967997
sf->addUnvalidatedDeclWithOpaqueResultType(VD);
79977998
}
79987999
});
@@ -8282,8 +8283,8 @@ ParserResult<FuncDecl> Parser::parseDeclFunc(SourceLoc StaticLoc,
82828283

82838284
// Let the source file track the opaque return type mapping, if any.
82848285
if (FuncRetTy && FuncRetTy->hasOpaque() &&
8285-
!InInactiveClauseEnvironment) {
8286-
if (auto sf = CurDeclContext->getParentSourceFile()) {
8286+
!InInactiveClauseEnvironment && !InFreestandingMacroArgument) {
8287+
if (auto sf = CurDeclContext->getOutermostParentSourceFile()) {
82878288
sf->addUnvalidatedDeclWithOpaqueResultType(FD);
82888289
}
82898290
}
@@ -9230,8 +9231,8 @@ Parser::parseDeclSubscript(SourceLoc StaticLoc,
92309231

92319232
// Let the source file track the opaque return type mapping, if any.
92329233
if (ElementTy.get() && ElementTy.get()->hasOpaque() &&
9233-
!InInactiveClauseEnvironment) {
9234-
if (auto sf = CurDeclContext->getParentSourceFile()) {
9234+
!InInactiveClauseEnvironment && !InFreestandingMacroArgument) {
9235+
if (auto sf = CurDeclContext->getOutermostParentSourceFile()) {
92359236
sf->addUnvalidatedDeclWithOpaqueResultType(Subscript);
92369237
}
92379238
}

lib/Parse/ParseExpr.cpp

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

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

lib/Sema/TypeCheckDeclPrimary.cpp

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

test/Macros/macro_expand.swift

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

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

0 commit comments

Comments
 (0)