Skip to content

Commit 06b73da

Browse files
authored
Merge pull request #39607 from etcwilde/ewilde/0323-async-main
Implementing 0323 async main
2 parents c177a16 + 01eebe1 commit 06b73da

31 files changed

+848
-297
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@ CHANGELOG
2929
Swift 5.5
3030
---------
3131

32+
* [SE-0323][]:
33+
34+
The main function is executed with `MainActor` isolation applied, so functions
35+
and variables with `MainActor` isolation may be called and modified
36+
synchronously from the main function. If the main function is annotated with a
37+
global actor explicitly, it must be the main actor or an error is emitted. If
38+
no global actor annotation is present, the main function is implicitly run on
39+
the main actor.
40+
41+
The main function is executed synchronously up to the first suspension point.
42+
Any tasks enqueued by initializers in Objective-C or C++ will run after the
43+
main function runs to the first suspension point. At the suspension point, the
44+
main function suspends and the tasks are executed according to the Swift
45+
concurrency mechanisms.
46+
3247
* [SE-0313][]:
3348

3449
Parameters of actor type can be declared as `isolated`, which means that they

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4289,6 +4289,10 @@ NOTE(note_add_globalactor_to_function,none,
42894289
"add '@%0' to make %1 %2 part of global actor %3",
42904290
(StringRef, DescriptiveDeclKind, DeclName, Type))
42914291
FIXIT(insert_globalactor_attr, "@%0 ", (Type))
4292+
4293+
ERROR(main_function_must_be_mainActor,none,
4294+
"main() must be '@MainActor'", ())
4295+
42924296
ERROR(not_objc_function_async,none,
42934297
"'async' %0 cannot be represented in Objective-C", (DescriptiveDeclKind))
42944298
NOTE(not_objc_function_type_async,none,

include/swift/AST/FileUnit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ class FileUnit : public DeclContext {
273273
return dyn_cast_or_null<ClassDecl>(getMainDecl());
274274
}
275275
bool hasMainDecl() const { return getMainDecl(); }
276-
virtual Decl *getMainDecl() const { return nullptr; }
276+
virtual ValueDecl *getMainDecl() const { return nullptr; }
277277
FuncDecl *getMainFunc() const {
278278
return dyn_cast_or_null<FuncDecl>(getMainDecl());
279279
}

include/swift/AST/SourceFile.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class SourceFile final : public FileUnit {
9999

100100
/// Either the class marked \@NS/UIApplicationMain or the synthesized FuncDecl
101101
/// that calls main on the type marked @main.
102-
Decl *MainDecl = nullptr;
102+
ValueDecl *MainDecl = nullptr;
103103

104104
/// The source location of the main type.
105105
SourceLoc MainDeclDiagLoc;
@@ -488,7 +488,7 @@ class SourceFile final : public FileUnit {
488488
llvm_unreachable("bad SourceFileKind");
489489
}
490490

491-
Decl *getMainDecl() const override { return MainDecl; }
491+
ValueDecl *getMainDecl() const override { return MainDecl; }
492492
SourceLoc getMainDeclDiagLoc() const {
493493
assert(hasMainDecl());
494494
return MainDeclDiagLoc;
@@ -502,7 +502,7 @@ class SourceFile final : public FileUnit {
502502
/// one.
503503
///
504504
/// Should only be called during type-checking.
505-
bool registerMainDecl(Decl *mainDecl, SourceLoc diagLoc);
505+
bool registerMainDecl(ValueDecl *mainDecl, SourceLoc diagLoc);
506506

507507
/// True if this source file has an application entry point.
508508
///

include/swift/AST/TypeAlignments.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ namespace swift {
3838
class DifferentiableAttr;
3939
class Expr;
4040
class ExtensionDecl;
41+
class FileUnit;
4142
class GenericEnvironment;
4243
class GenericParamList;
4344
class GenericTypeParamDecl;
@@ -123,6 +124,7 @@ LLVM_DECLARE_TYPE_ALIGNMENT(swift::BraceStmt, swift::StmtAlignInBits)
123124

124125
LLVM_DECLARE_TYPE_ALIGNMENT(swift::ASTContext, swift::ASTContextAlignInBits);
125126
LLVM_DECLARE_TYPE_ALIGNMENT(swift::DeclContext, swift::DeclContextAlignInBits)
127+
LLVM_DECLARE_TYPE_ALIGNMENT(swift::FileUnit, swift::DeclContextAlignInBits)
126128
LLVM_DECLARE_TYPE_ALIGNMENT(swift::DifferentiableAttr, swift::PointerAlignInBits)
127129
LLVM_DECLARE_TYPE_ALIGNMENT(swift::Expr, swift::ExprAlignInBits)
128130
LLVM_DECLARE_TYPE_ALIGNMENT(swift::CaptureListExpr, swift::ExprAlignInBits)

include/swift/SIL/SILDeclRef.h

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ namespace swift {
4242
class AutoClosureExpr;
4343
class ASTContext;
4444
class ClassDecl;
45+
class FileUnit;
4546
class SILFunctionType;
4647
enum IsSerialized_t : unsigned char;
4748
enum class SubclassScope : unsigned char;
@@ -83,7 +84,14 @@ enum ForDefinition_t : bool {
8384
/// declaration, such as uncurry levels of a function, the allocating and
8485
/// initializing entry points of a constructor, etc.
8586
struct SILDeclRef {
86-
using Loc = llvm::PointerUnion<ValueDecl *, AbstractClosureExpr *>;
87+
/// The type of AST node location being stored.
88+
enum LocKind {
89+
Decl,
90+
Closure,
91+
File
92+
};
93+
using Loc = llvm::PointerUnion<ValueDecl *, AbstractClosureExpr *,
94+
FileUnit *>;
8795

8896
/// Represents the "kind" of the SILDeclRef. For some Swift decls there
8997
/// are multiple SIL entry points, and the kind is used to distinguish them.
@@ -144,9 +152,16 @@ struct SILDeclRef {
144152
/// References the function used to initialize a property wrapper storage
145153
/// instance from a projected value.
146154
PropertyWrapperInitFromProjectedValue,
155+
156+
/// The main entry-point function. This may reference a SourceFile for a
157+
/// top-level main, or a decl for e.g an @main decl.
158+
EntryPoint,
159+
160+
/// The asynchronous main entry-point function.
161+
AsyncEntryPoint,
147162
};
148-
149-
/// The ValueDecl or AbstractClosureExpr represented by this SILDeclRef.
163+
164+
/// The AST node represented by this SILDeclRef.
150165
Loc loc;
151166
/// The Kind of this SILDeclRef.
152167
Kind kind : 4;
@@ -159,6 +174,17 @@ struct SILDeclRef {
159174
const GenericSignatureImpl *>
160175
pointer;
161176

177+
/// Returns the type of AST node location being stored by the SILDeclRef.
178+
LocKind getLocKind() const {
179+
if (loc.is<ValueDecl *>())
180+
return LocKind::Decl;
181+
if (loc.is<AbstractClosureExpr *>())
182+
return LocKind::Closure;
183+
if (loc.is<FileUnit *>())
184+
return LocKind::File;
185+
llvm_unreachable("Unhandled location kind!");
186+
}
187+
162188
/// The derivative function identifier.
163189
AutoDiffDerivativeFunctionIdentifier * getDerivativeFunctionIdentifier() const {
164190
if (!pointer.is<AutoDiffDerivativeFunctionIdentifier *>())
@@ -201,6 +227,15 @@ struct SILDeclRef {
201227
/// Produce a SIL constant for a default argument generator.
202228
static SILDeclRef getDefaultArgGenerator(Loc loc, unsigned defaultArgIndex);
203229

230+
/// Produces a SILDeclRef for a synthetic main entry-point such as @main.
231+
static SILDeclRef getMainDeclEntryPoint(ValueDecl *decl);
232+
233+
/// Produces a SILDeclRef for the synthesized async main entry-point
234+
static SILDeclRef getAsyncMainDeclEntryPoint(ValueDecl *decl);
235+
236+
/// Produces a SILDeclRef for the entry-point of a main FileUnit.
237+
static SILDeclRef getMainFileEntryPoint(FileUnit *file);
238+
204239
bool isNull() const { return loc.isNull(); }
205240
explicit operator bool() const { return !isNull(); }
206241

@@ -217,7 +252,13 @@ struct SILDeclRef {
217252
AutoClosureExpr *getAutoClosureExpr() const;
218253
FuncDecl *getFuncDecl() const;
219254
AbstractFunctionDecl *getAbstractFunctionDecl() const;
220-
255+
FileUnit *getFileUnit() const {
256+
return loc.get<FileUnit *>();
257+
}
258+
259+
/// Retrieves the ASTContext from the underlying AST node being stored.
260+
ASTContext &getASTContext() const;
261+
221262
llvm::Optional<AnyFunctionRef> getAnyFunctionRef() const;
222263

223264
SILLocation getAsRegularLocation() const;

include/swift/Serialization/SerializedModuleLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ class SerializedASTFile final : public LoadedFile {
433433

434434
virtual StringRef getModuleDefiningPath() const override;
435435

436-
Decl *getMainDecl() const override;
436+
ValueDecl *getMainDecl() const override;
437437

438438
bool hasEntryPoint() const override;
439439

lib/AST/Module.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1590,7 +1590,7 @@ bool ModuleDecl::isBuiltinModule() const {
15901590
return this == getASTContext().TheBuiltinModule;
15911591
}
15921592

1593-
bool SourceFile::registerMainDecl(Decl *mainDecl, SourceLoc diagLoc) {
1593+
bool SourceFile::registerMainDecl(ValueDecl *mainDecl, SourceLoc diagLoc) {
15941594
assert(mainDecl);
15951595
if (mainDecl == MainDecl)
15961596
return false;

lib/IRGen/GenObjC.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@ namespace {
473473
case SILDeclRef::Kind::GlobalAccessor:
474474
case SILDeclRef::Kind::PropertyWrapperBackingInitializer:
475475
case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue:
476+
case SILDeclRef::Kind::EntryPoint:
477+
case SILDeclRef::Kind::AsyncEntryPoint:
476478
llvm_unreachable("Method does not have a selector");
477479

478480
case SILDeclRef::Kind::Destroyer:

0 commit comments

Comments
 (0)