Skip to content

Commit 3b90b08

Browse files
committed
Use presence of 'await' to make top-level async
To help maintain source-compatibility, the presence of an `await` in top-level code to kick the top-level code over to being a concurrent context. This, of course, means that in the test cases that exist today, they will go back to behaving identically to how they did before I added all of this because they don't have any awaits in the top-level. I'll be adding new tests to verify the differences in behavior between swift 5, swift 6, with and without async top level enabled in the next commit.
1 parent 4b182f6 commit 3b90b08

File tree

7 files changed

+52
-21
lines changed

7 files changed

+52
-21
lines changed

include/swift/AST/SourceFile.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,9 @@ class SourceFile final : public FileUnit {
582582

583583
ArrayRef<OpaqueTypeDecl *> getOpaqueReturnTypeDecls();
584584

585+
/// Returns true if the source file contains concurrency in the top-level
586+
bool isAsyncTopLevelSourceFile() const;
587+
585588
private:
586589

587590
/// If not \c None, the underlying vector contains the parsed tokens of this

include/swift/AST/TypeCheckRequests.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3246,6 +3246,21 @@ class ClosureEffectsRequest
32463246
bool isCached() const { return true; }
32473247
};
32483248

3249+
class GetSourceFileAsyncNode
3250+
: public SimpleRequest<GetSourceFileAsyncNode, ASTNode(const SourceFile *),
3251+
RequestFlags::Cached> {
3252+
public:
3253+
using SimpleRequest::SimpleRequest;
3254+
3255+
private:
3256+
friend SimpleRequest;
3257+
3258+
ASTNode evaluate(Evaluator &evaluator, const SourceFile *) const;
3259+
3260+
public:
3261+
bool isCached() const { return true; }
3262+
};
3263+
32493264
void simple_display(llvm::raw_ostream &out, Type value);
32503265
void simple_display(llvm::raw_ostream &out, const TypeRepr *TyR);
32513266
void simple_display(llvm::raw_ostream &out, ImplicitMemberAction action);

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,3 +372,6 @@ SWIFT_REQUEST(TypeChecker, RenamedDeclRequest,
372372
SWIFT_REQUEST(TypeChecker, ClosureEffectsRequest,
373373
FunctionType::ExtInfo(ClosureExpr *),
374374
Cached, NoLocationInfo)
375+
SWIFT_REQUEST(TypeChecker, GetSourceFileAsyncNode,
376+
AwaitExpr *(const SourceFile *),
377+
Cached, NoLocationInfo)

lib/AST/DeclContext.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1228,8 +1228,13 @@ bool DeclContext::isAsyncContext() const {
12281228
case DeclContextKind::GenericTypeDecl:
12291229
return false;
12301230
case DeclContextKind::FileUnit:
1231+
if (const SourceFile *sf = dyn_cast<SourceFile>(this))
1232+
return getASTContext().LangOpts.EnableExperimentalAsyncTopLevel &&
1233+
sf->isAsyncTopLevelSourceFile();
1234+
return false;
12311235
case DeclContextKind::TopLevelCodeDecl:
1232-
return getASTContext().LangOpts.EnableExperimentalAsyncTopLevel;
1236+
return getASTContext().LangOpts.EnableExperimentalAsyncTopLevel &&
1237+
getParent()->isAsyncContext();
12331238
case DeclContextKind::AbstractClosureExpr:
12341239
return cast<AbstractClosureExpr>(this)->isBodyAsync();
12351240
case DeclContextKind::AbstractFunctionDecl: {

lib/AST/Module.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3038,6 +3038,24 @@ SourceFile::lookupOpaqueResultType(StringRef MangledName) {
30383038
return nullptr;
30393039
}
30403040

3041+
bool SourceFile::isAsyncTopLevelSourceFile() const {
3042+
return isScriptMode() &&
3043+
(bool)evaluateOrDefault(getASTContext().evaluator,
3044+
GetSourceFileAsyncNode{this}, ASTNode());
3045+
}
3046+
3047+
ASTNode GetSourceFileAsyncNode::evaluate(Evaluator &eval,
3048+
const SourceFile *sf) const {
3049+
for (Decl *d : sf->getTopLevelDecls()) {
3050+
TopLevelCodeDecl *tld = dyn_cast<TopLevelCodeDecl>(d);
3051+
if (tld && tld->getBody()) {
3052+
if (ASTNode asyncNode = tld->getBody()->findAsyncNode())
3053+
return asyncNode;
3054+
}
3055+
}
3056+
return ASTNode();
3057+
}
3058+
30413059
//===----------------------------------------------------------------------===//
30423060
// SynthesizedFileUnit Implementation
30433061
//===----------------------------------------------------------------------===//

test/SILGen/toplevel.swift

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-swift-emit-silgen -Xllvm -sil-full-demangle %s | %FileCheck %s --check-prefixes='CHECK,SYNC-CHECK'
2-
// RUN: %target-swift-emit-silgen -Xllvm -sil-full-demangle -enable-experimental-async-top-level %s | %FileCheck %s --check-prefixes='CHECK,ASYNC-CHECK'
1+
// RUN: %target-swift-emit-silgen -Xllvm -sil-full-demangle %s | %FileCheck %s
2+
// RUN: %target-swift-emit-silgen -Xllvm -sil-full-demangle -enable-experimental-async-top-level %s | %FileCheck %s
33

44
func markUsed<T>(_ t: T) {}
55

@@ -11,13 +11,7 @@ func trap() -> Never {
1111
// CHECK-LABEL: sil [ossa] @main
1212
// CHECK: bb0({{%.*}} : $Int32, {{%.*}} : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
1313

14-
// async setup call to @async_Main (this is in @main)
15-
// ASYNC-CHECK: [[ASYNC_MAIN:%[0-9]+]] = function_ref @async_Main : $@convention(thin) @async () -> ()
16-
// ASYNC-CHECK: [[THUNK:%[0-9]+]] = function_ref @$sIetH_yts5Error_pIegHrzo_TR
17-
18-
// Actual body of async top-level
19-
// ASYNC-CHECK-LABEL: sil hidden [ossa] @async_Main
20-
// ASYNC-CHECK: bb0:
14+
// CHECK-NOT: @async_Main
2115

2216

2317
// -- initialize x
@@ -127,11 +121,7 @@ defer {
127121

128122

129123
// CHECK: [[RET:%[0-9]+]] = struct $Int32
130-
// SYNC-CHECK: return [[RET]]
131-
132-
// ASYNC-CHECK: [[EXITFUNC:%[0-9]+]] = function_ref @exit
133-
// ASYNC-CHECK: apply [[EXITFUNC]]([[RET]]) : $@convention(c) (Int32) -> Never
134-
// ASYNC-CHECK: unreachable
124+
// CHECK: return [[RET]]
135125

136126
// CHECK-LABEL: sil hidden [ossa] @$s8toplevel7print_xyyF
137127

test/SILGen/toplevel_errors.swift

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-swift-emit-silgen %s | %FileCheck %s --check-prefixes='CHECK,SYNC-CHECK'
2-
// RUN: %target-swift-emit-silgen -enable-experimental-async-top-level %s | %FileCheck %s --check-prefixes='CHECK,ASYNC-CHECK'
1+
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
2+
// RUN: %target-swift-emit-silgen -enable-experimental-async-top-level %s | %FileCheck %s
33

44
enum MyError : Error {
55
case A, B
@@ -18,10 +18,7 @@ throw MyError.A
1818
// CHECK: br bb2([[ERR2]] : $Error)
1919

2020
// CHECK: bb1([[T0:%.*]] : $Int32):
21-
// SYNC-CHECK: return [[T0]] : $Int32
22-
// ASYNC-CHECK: [[EXITFUNC:%[0-9]+]] = function_ref @exit
23-
// ASYNC-CHECK: {{[0-9]+}} = apply [[EXITFUNC]]([[T0]])
24-
// ASYNC-CHECK: unreachable
21+
// CHECK: return [[T0]] : $Int32
2522

2623
// CHECK: bb2([[T0:%.*]] : @owned $Error):
2724
// CHECK: builtin "errorInMain"([[T0]] : $Error)

0 commit comments

Comments
 (0)