Skip to content

Implementing 0323 async main #39607

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 15 commits into from
Oct 12, 2021
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
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,21 @@ CHANGELOG
Swift 5.5
---------

* [SE-0323][]:

The main function is executed with `MainActor` isolation applied, so functions
and variables with `MainActor` isolation may be called and modified
synchronously from the main function. If the main function is annotated with a
global actor explicitly, it must be the main actor or an error is emitted. If
no global actor annotation is present, the main function is implicitly run on
the main actor.

The main function is executed synchronously up to the first suspension point.
Any tasks enqueued by initializers in Objective-C or C++ will run after the
main function runs to the first suspension point. At the suspension point, the
main function suspends and the tasks are executed according to the Swift
concurrency mechanisms.

* [SE-0313][]:

Parameters of actor type can be declared as `isolated`, which means that they
Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -4289,6 +4289,10 @@ NOTE(note_add_globalactor_to_function,none,
"add '@%0' to make %1 %2 part of global actor %3",
(StringRef, DescriptiveDeclKind, DeclName, Type))
FIXIT(insert_globalactor_attr, "@%0 ", (Type))

ERROR(main_function_must_be_mainActor,none,
"main() must be '@MainActor'", ())

ERROR(not_objc_function_async,none,
"'async' %0 cannot be represented in Objective-C", (DescriptiveDeclKind))
NOTE(not_objc_function_type_async,none,
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/FileUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ class FileUnit : public DeclContext {
return dyn_cast_or_null<ClassDecl>(getMainDecl());
}
bool hasMainDecl() const { return getMainDecl(); }
virtual Decl *getMainDecl() const { return nullptr; }
virtual ValueDecl *getMainDecl() const { return nullptr; }
FuncDecl *getMainFunc() const {
return dyn_cast_or_null<FuncDecl>(getMainDecl());
}
Expand Down
6 changes: 3 additions & 3 deletions include/swift/AST/SourceFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class SourceFile final : public FileUnit {

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

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

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

/// True if this source file has an application entry point.
///
Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/TypeAlignments.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace swift {
class DifferentiableAttr;
class Expr;
class ExtensionDecl;
class FileUnit;
class GenericEnvironment;
class GenericParamList;
class GenericTypeParamDecl;
Expand Down Expand Up @@ -123,6 +124,7 @@ LLVM_DECLARE_TYPE_ALIGNMENT(swift::BraceStmt, swift::StmtAlignInBits)

LLVM_DECLARE_TYPE_ALIGNMENT(swift::ASTContext, swift::ASTContextAlignInBits);
LLVM_DECLARE_TYPE_ALIGNMENT(swift::DeclContext, swift::DeclContextAlignInBits)
LLVM_DECLARE_TYPE_ALIGNMENT(swift::FileUnit, swift::DeclContextAlignInBits)
LLVM_DECLARE_TYPE_ALIGNMENT(swift::DifferentiableAttr, swift::PointerAlignInBits)
LLVM_DECLARE_TYPE_ALIGNMENT(swift::Expr, swift::ExprAlignInBits)
LLVM_DECLARE_TYPE_ALIGNMENT(swift::CaptureListExpr, swift::ExprAlignInBits)
Expand Down
49 changes: 45 additions & 4 deletions include/swift/SIL/SILDeclRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ namespace swift {
class AutoClosureExpr;
class ASTContext;
class ClassDecl;
class FileUnit;
class SILFunctionType;
enum IsSerialized_t : unsigned char;
enum class SubclassScope : unsigned char;
Expand Down Expand Up @@ -83,7 +84,14 @@ enum ForDefinition_t : bool {
/// declaration, such as uncurry levels of a function, the allocating and
/// initializing entry points of a constructor, etc.
struct SILDeclRef {
using Loc = llvm::PointerUnion<ValueDecl *, AbstractClosureExpr *>;
/// The type of AST node location being stored.
enum LocKind {
Decl,
Closure,
File
};
using Loc = llvm::PointerUnion<ValueDecl *, AbstractClosureExpr *,
FileUnit *>;

/// Represents the "kind" of the SILDeclRef. For some Swift decls there
/// are multiple SIL entry points, and the kind is used to distinguish them.
Expand Down Expand Up @@ -144,9 +152,16 @@ struct SILDeclRef {
/// References the function used to initialize a property wrapper storage
/// instance from a projected value.
PropertyWrapperInitFromProjectedValue,

/// The main entry-point function. This may reference a SourceFile for a
/// top-level main, or a decl for e.g an @main decl.
EntryPoint,

/// The asynchronous main entry-point function.
AsyncEntryPoint,
};
/// The ValueDecl or AbstractClosureExpr represented by this SILDeclRef.

/// The AST node represented by this SILDeclRef.
Loc loc;
/// The Kind of this SILDeclRef.
Kind kind : 4;
Expand All @@ -159,6 +174,17 @@ struct SILDeclRef {
const GenericSignatureImpl *>
pointer;

/// Returns the type of AST node location being stored by the SILDeclRef.
LocKind getLocKind() const {
if (loc.is<ValueDecl *>())
return LocKind::Decl;
if (loc.is<AbstractClosureExpr *>())
return LocKind::Closure;
if (loc.is<FileUnit *>())
return LocKind::File;
llvm_unreachable("Unhandled location kind!");
}

/// The derivative function identifier.
AutoDiffDerivativeFunctionIdentifier * getDerivativeFunctionIdentifier() const {
if (!pointer.is<AutoDiffDerivativeFunctionIdentifier *>())
Expand Down Expand Up @@ -201,6 +227,15 @@ struct SILDeclRef {
/// Produce a SIL constant for a default argument generator.
static SILDeclRef getDefaultArgGenerator(Loc loc, unsigned defaultArgIndex);

/// Produces a SILDeclRef for a synthetic main entry-point such as @main.
static SILDeclRef getMainDeclEntryPoint(ValueDecl *decl);

/// Produces a SILDeclRef for the synthesized async main entry-point
static SILDeclRef getAsyncMainDeclEntryPoint(ValueDecl *decl);

/// Produces a SILDeclRef for the entry-point of a main FileUnit.
static SILDeclRef getMainFileEntryPoint(FileUnit *file);

bool isNull() const { return loc.isNull(); }
explicit operator bool() const { return !isNull(); }

Expand All @@ -217,7 +252,13 @@ struct SILDeclRef {
AutoClosureExpr *getAutoClosureExpr() const;
FuncDecl *getFuncDecl() const;
AbstractFunctionDecl *getAbstractFunctionDecl() const;

FileUnit *getFileUnit() const {
return loc.get<FileUnit *>();
}

/// Retrieves the ASTContext from the underlying AST node being stored.
ASTContext &getASTContext() const;

llvm::Optional<AnyFunctionRef> getAnyFunctionRef() const;

SILLocation getAsRegularLocation() const;
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Serialization/SerializedModuleLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ class SerializedASTFile final : public LoadedFile {

virtual StringRef getModuleDefiningPath() const override;

Decl *getMainDecl() const override;
ValueDecl *getMainDecl() const override;

bool hasEntryPoint() const override;

Expand Down
2 changes: 1 addition & 1 deletion lib/AST/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1587,7 +1587,7 @@ bool ModuleDecl::isBuiltinModule() const {
return this == getASTContext().TheBuiltinModule;
}

bool SourceFile::registerMainDecl(Decl *mainDecl, SourceLoc diagLoc) {
bool SourceFile::registerMainDecl(ValueDecl *mainDecl, SourceLoc diagLoc) {
assert(mainDecl);
if (mainDecl == MainDecl)
return false;
Expand Down
2 changes: 2 additions & 0 deletions lib/IRGen/GenObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,8 @@ namespace {
case SILDeclRef::Kind::GlobalAccessor:
case SILDeclRef::Kind::PropertyWrapperBackingInitializer:
case SILDeclRef::Kind::PropertyWrapperInitFromProjectedValue:
case SILDeclRef::Kind::EntryPoint:
case SILDeclRef::Kind::AsyncEntryPoint:
llvm_unreachable("Method does not have a selector");

case SILDeclRef::Kind::Destroyer:
Expand Down
Loading