Skip to content

Commit 5bd96a4

Browse files
committed
@main: Added $main func to @main type.
Previously, the function was being added to the list of top level decls in the source file as that list was being iterated, leading to iterator issues. Here, the function is instead added to the nominal type decl which is decorated with @main. Doing so requires calling the $main function with the metatype for the nominal type. The workaround for the iterator invalidation issue which had been applied previously, namely changing the type of the Decls member of SourceFile from std::vector<Decl *> to SmallVector<Decl *, 16> is reverted.
1 parent f7e2abe commit 5bd96a4

File tree

2 files changed

+10
-7
lines changed

2 files changed

+10
-7
lines changed

lib/SILGen/SILGenFunction.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,9 +732,12 @@ void SILGenFunction::emitArtificialTopLevel(Decl *mainDecl) {
732732
SILFunction *mainFunction =
733733
SGM.getFunction(mainFunctionDeclRef, NotForDefinition);
734734

735+
NominalTypeDecl *mainType = cast<NominalTypeDecl>(mainFunc->getDeclContext());
736+
auto metatype = B.createMetatype(mainType, getLoweredType(mainType->getInterfaceType()));
737+
735738
auto mainFunctionRef = B.createFunctionRef(mainFunc, mainFunction);
736739

737-
B.createApply(mainFunc, mainFunctionRef, SubstitutionMap(), {});
740+
B.createApply(mainFunc, mainFunctionRef, SubstitutionMap(), {metatype});
738741

739742
SILValue returnValue = B.createIntegerLiteral(
740743
mainFunc, SILType::getBuiltinIntegerType(32, getASTContext()), 0);

lib/Sema/TypeCheckAttr.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,18 +1767,18 @@ void AttributeChecker::visitMainTypeAttr(MainTypeAttr *attr) {
17671767
}
17681768

17691769
auto voidToVoidFunctionType = FunctionType::get({}, context.TheEmptyTupleType);
1770+
auto nominalToVoidToVoidFunctionType = FunctionType::get({AnyFunctionType::Param(nominal->getInterfaceType())}, voidToVoidFunctionType);
17701771
auto *func = FuncDecl::create(
1771-
context, /*StaticLoc*/ SourceLoc(), StaticSpellingKind::None,
1772+
context, /*StaticLoc*/ nominal->getBraces().End, StaticSpellingKind::KeywordStatic,
17721773
/*FuncLoc*/ location,
17731774
DeclName(context, DeclBaseName(context.Id_MainEntryPoint),
17741775
ParameterList::createEmpty(context)),
1775-
/*NameLoc*/ SourceLoc(), /*Throws=*/false, /*ThrowsLoc=*/SourceLoc(),
1776+
/*NameLoc*/ nominal->getBraces().End, /*Throws=*/false, /*ThrowsLoc=*/SourceLoc(),
17761777
/*GenericParams=*/nullptr, ParameterList::createEmpty(context),
17771778
/*FnRetType=*/TypeLoc::withoutLoc(TupleType::getEmpty(context)),
1778-
nominal->getParentSourceFile());
1779+
nominal);
17791780
func->setImplicit(true);
17801781
func->setSynthesized(true);
1781-
func->setInterfaceType(voidToVoidFunctionType);
17821782

17831783
auto *typeExpr = TypeExpr::createImplicit(nominal->getDeclaredType(), context);
17841784

@@ -1815,9 +1815,9 @@ void AttributeChecker::visitMainTypeAttr(MainTypeAttr *attr) {
18151815
auto *body = BraceStmt::create(context, SourceLoc(), stmts,
18161816
SourceLoc(), /*Implicit*/true);
18171817
func->setBodyParsed(body);
1818-
func->setInterfaceType(voidToVoidFunctionType);
1818+
func->setInterfaceType(nominalToVoidToVoidFunctionType);
18191819

1820-
nominal->getParentSourceFile()->addTopLevelDecl(func);
1820+
nominal->addMember(func);
18211821
// This function must be type-checked. Why? Consider the following scenario:
18221822
//
18231823
// protocol AlmostMainable {}

0 commit comments

Comments
 (0)