Skip to content

[6.0] AST: Fix availability checking for macros as default arguments #72828

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
5 changes: 5 additions & 0 deletions include/swift/AST/SourceFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,11 @@ class SourceFile final : public FileUnit {
/// enclosed in.
SourceFile *getEnclosingSourceFile() const;

/// If this file has an enclosing source file (because it is the result of
/// expanding a macro or default argument), returns the node in the enclosing
/// file that this file's contents were expanded from.
ASTNode getNodeInEnclosingSourceFile() const;

/// If this buffer corresponds to a file on disk, returns the path.
/// Otherwise, return an empty string.
StringRef getFilename() const;
Expand Down
4 changes: 2 additions & 2 deletions include/swift/AST/TypeRefinementContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,8 @@ class TypeRefinementContext : public ASTAllocated<TypeRefinementContext> {
public:

/// Create the root refinement context for the given SourceFile.
static TypeRefinementContext *createRoot(SourceFile *SF,
const AvailabilityContext &Info);
static TypeRefinementContext *
createForSourceFile(SourceFile *SF, const AvailabilityContext &Info);

/// Create a refinement context for the given declaration.
static TypeRefinementContext *createForDecl(ASTContext &Ctx, Decl *D,
Expand Down
14 changes: 11 additions & 3 deletions lib/AST/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1179,9 +1179,7 @@ ASTNode SourceFile::getMacroExpansion() const {
if (Kind != SourceFileKind::MacroExpansion)
return nullptr;

auto genInfo =
*getASTContext().SourceMgr.getGeneratedSourceInfo(*getBufferID());
return ASTNode::getFromOpaqueValue(genInfo.astNode);
return getNodeInEnclosingSourceFile();
}

SourceRange SourceFile::getMacroInsertionRange() const {
Expand Down Expand Up @@ -1233,6 +1231,16 @@ SourceFile *SourceFile::getEnclosingSourceFile() const {
return getParentModule()->getSourceFileContainingLocation(sourceLoc);
}

ASTNode SourceFile::getNodeInEnclosingSourceFile() const {
if (Kind != SourceFileKind::MacroExpansion &&
Kind != SourceFileKind::DefaultArgument)
return nullptr;

auto genInfo =
*getASTContext().SourceMgr.getGeneratedSourceInfo(*getBufferID());
return ASTNode::getFromOpaqueValue(genInfo.astNode);
}

void ModuleDecl::lookupClassMember(ImportPath::Access accessPath,
DeclName name,
SmallVectorImpl<ValueDecl*> &results) const {
Expand Down
26 changes: 20 additions & 6 deletions lib/AST/TypeRefinementContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,38 @@ TypeRefinementContext::TypeRefinementContext(ASTContext &Ctx, IntroNode Node,
}

TypeRefinementContext *
TypeRefinementContext::createRoot(SourceFile *SF,
const AvailabilityContext &Info) {
TypeRefinementContext::createForSourceFile(SourceFile *SF,
const AvailabilityContext &Info) {
assert(SF);

ASTContext &Ctx = SF->getASTContext();

SourceRange range;
TypeRefinementContext *parentContext = nullptr;
AvailabilityContext availabilityContext = Info;
if (auto parentExpansion = SF->getMacroExpansion()) {
switch (SF->Kind) {
case SourceFileKind::MacroExpansion:
case SourceFileKind::DefaultArgument: {
// Look up the parent context in the enclosing file that this file's
// root context should be nested under.
if (auto parentTRC =
SF->getEnclosingSourceFile()->getTypeRefinementContext()) {
auto charRange = Ctx.SourceMgr.getRangeForBuffer(*SF->getBufferID());
range = SourceRange(charRange.getStart(), charRange.getEnd());
parentContext = parentTRC->findMostRefinedSubContext(
parentExpansion.getStartLoc(), Ctx);
availabilityContext = parentContext->getAvailabilityInfo();
auto originalNode = SF->getNodeInEnclosingSourceFile();
parentContext =
parentTRC->findMostRefinedSubContext(originalNode.getStartLoc(), Ctx);
if (parentContext)
availabilityContext = parentContext->getAvailabilityInfo();
}
break;
}
case SourceFileKind::Library:
case SourceFileKind::Main:
case SourceFileKind::Interface:
break;
case SourceFileKind::SIL:
llvm_unreachable("unexpected SourceFileKind");
}

return new (Ctx)
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/TypeCheckAvailability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1279,7 +1279,7 @@ void TypeChecker::buildTypeRefinementContextHierarchy(SourceFile &SF) {
// the source file are guaranteed to be executing on at least the minimum
// platform version for inlining.
auto MinPlatformReq = AvailabilityContext::forInliningTarget(Context);
RootTRC = TypeRefinementContext::createRoot(&SF, MinPlatformReq);
RootTRC = TypeRefinementContext::createForSourceFile(&SF, MinPlatformReq);
SF.setTypeRefinementContext(RootTRC);
}

Expand Down
25 changes: 25 additions & 0 deletions test/Concurrency/isolation_macro_availability.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: %target-typecheck-verify-swift

// REQUIRES: concurrency
// REQUIRES: swift_swift_parser
// REQUIRES: VENDOR=apple

@available(SwiftStdlib 5.1, *)
func isolatedFunc(isolation: isolated (any Actor)? = #isolation) {}

func test() { // expected-note 3 {{add @available attribute to enclosing global function}}
_ = #isolation // expected-error {{'isolation()' is only available in}} expected-note {{add 'if #available' version check}}
isolatedFunc() // expected-error {{'isolatedFunc(isolation:)' is only available in}} expected-note {{add 'if #available' version check}}
// expected-error@-1 {{'isolation()' is only available in}}

if #available(SwiftStdlib 5.1, *) {
_ = #isolation
isolatedFunc()
}
}

@available(SwiftStdlib 5.1, *)
func testAvailable5_1() {
_ = #isolation
isolatedFunc()
}