Skip to content

[Macros] Cope with local types and opaque result types in macros and expansions. #67099

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ class Parser {
/// ASTScopes are not created in inactive clauses and lookups to decls will fail.
bool InInactiveClauseEnvironment = false;
bool InSwiftKeyPath = false;
bool InFreestandingMacroArgument = false;

/// Whether we should delay parsing nominal type, extension, and function
/// bodies.
Expand Down
4 changes: 2 additions & 2 deletions lib/AST/TypeSubstitution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1043,8 +1043,8 @@ static bool canSubstituteTypeInto(Type ty, const DeclContext *dc,

// In the same file any visibility is okay.
if (!dc->isModuleContext() &&
typeDecl->getDeclContext()->getParentSourceFile() ==
dc->getParentSourceFile())
typeDecl->getDeclContext()->getOutermostParentSourceFile() ==
dc->getOutermostParentSourceFile())
return true;

return typeDecl->getEffectiveAccess() > AccessLevel::FilePrivate;
Expand Down
15 changes: 8 additions & 7 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5209,7 +5209,7 @@ void Parser::recordLocalType(TypeDecl *TD) {
if (!TD->getDeclContext()->isLocalContext())
return;

if (!InInactiveClauseEnvironment)
if (!InInactiveClauseEnvironment && !InFreestandingMacroArgument)
SF.getOutermostParentSourceFile()->LocalTypeDecls.insert(TD);
}

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

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

Decls.push_back(VD);
if (hasOpaqueReturnTy && sf && !InInactiveClauseEnvironment) {
if (hasOpaqueReturnTy && sf && !InInactiveClauseEnvironment
&& !InFreestandingMacroArgument) {
sf->addUnvalidatedDeclWithOpaqueResultType(VD);
}
});
Expand Down Expand Up @@ -8282,8 +8283,8 @@ ParserResult<FuncDecl> Parser::parseDeclFunc(SourceLoc StaticLoc,

// Let the source file track the opaque return type mapping, if any.
if (FuncRetTy && FuncRetTy->hasOpaque() &&
!InInactiveClauseEnvironment) {
if (auto sf = CurDeclContext->getParentSourceFile()) {
!InInactiveClauseEnvironment && !InFreestandingMacroArgument) {
if (auto sf = CurDeclContext->getOutermostParentSourceFile()) {
sf->addUnvalidatedDeclWithOpaqueResultType(FD);
}
}
Expand Down Expand Up @@ -9230,8 +9231,8 @@ Parser::parseDeclSubscript(SourceLoc StaticLoc,

// Let the source file track the opaque return type mapping, if any.
if (ElementTy.get() && ElementTy.get()->hasOpaque() &&
!InInactiveClauseEnvironment) {
if (auto sf = CurDeclContext->getParentSourceFile()) {
!InInactiveClauseEnvironment && !InFreestandingMacroArgument) {
if (auto sf = CurDeclContext->getOutermostParentSourceFile()) {
sf->addUnvalidatedDeclWithOpaqueResultType(Subscript);
}
}
Expand Down
2 changes: 2 additions & 0 deletions lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2338,6 +2338,8 @@ ParserStatus Parser::parseFreestandingMacroExpansion(
diagnose(leftAngleLoc, diag::while_parsing_as_left_angle_bracket);
}

llvm::SaveAndRestore<bool> inMacroArgument(InFreestandingMacroArgument, true);

if (Tok.isFollowingLParen()) {
auto result = parseArgumentList(tok::l_paren, tok::r_paren, isExprBasic,
/*allowTrailingClosure*/ true);
Expand Down
4 changes: 4 additions & 0 deletions lib/Sema/TypeCheckDeclPrimary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1850,6 +1850,10 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
ASTContext &getASTContext() const { return Ctx; }
void addDelayedFunction(AbstractFunctionDecl *AFD) {
if (!SF) return;

while (auto enclosingSF = SF->getEnclosingSourceFile())
SF = enclosingSF;

SF->DelayedFunctions.push_back(AFD);
}

Expand Down
16 changes: 16 additions & 0 deletions test/Macros/macro_expand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,22 @@ public struct Outer {
// CHECK: (2, "a + b")
testStringify(a: 1, b: 1)

protocol P { }
extension Int: P { }

// Stringify with closures that have local types.
@available(SwiftStdlib 5.1, *)
func testStringifyWithLocalTypes() {
_ = #stringify({
struct LocalType: P {
static var name: String = "Taylor"
var something: some P { self }
}

func f() -> some P { return LocalType().something }
})
}

func maybeThrowing() throws -> Int { 5 }

#if TEST_DIAGNOSTICS
Expand Down