Skip to content

Commit d7ea96b

Browse files
committed
Parse a general function-signature for an initializer.
This helps unify the parse trees with function declarations.
1 parent 6552d86 commit d7ea96b

File tree

4 files changed

+42
-25
lines changed

4 files changed

+42
-25
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,8 @@ ERROR(expected_lparen_initializer,PointsToFirstBadToken,
422422
"expected '(' for initializer parameters", ())
423423
ERROR(initializer_has_name,PointsToFirstBadToken,
424424
"initializers cannot have a name", ())
425+
ERROR(initializer_result_type,PointsToFirstBadToken,
426+
"initializers cannot have a result type", ())
425427

426428
// Destructor
427429
ERROR(destructor_decl_outside_class,none,

include/swift/Parse/Parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1460,7 +1460,7 @@ class Parser {
14601460
ParameterList *&BodyParams,
14611461
ParameterContextKind paramContext,
14621462
DefaultArgumentInfo &defaultArgs);
1463-
ParserStatus parseFunctionSignature(Identifier functionName,
1463+
ParserStatus parseFunctionSignature(DeclBaseName functionName,
14641464
DeclName &fullName,
14651465
ParameterList *&bodyParams,
14661466
DefaultArgumentInfo &defaultArgs,

lib/Parse/ParseDecl.cpp

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8395,13 +8395,20 @@ Parser::parseDeclInit(ParseDeclOptions Flags, DeclAttributes &Attributes) {
83958395
return Status;
83968396
}
83978397

8398-
// Parse the parameters.
83998398
DefaultArgumentInfo DefaultArgs;
8400-
llvm::SmallVector<Identifier, 4> namePieces;
8401-
ParserResult<ParameterList> Params
8402-
= parseSingleParameterClause(ParameterContextKind::Initializer,
8403-
&namePieces, &DefaultArgs);
8404-
Status |= Params;
8399+
TypeRepr *FuncRetTy = nullptr;
8400+
DeclName FullName;
8401+
ParameterList *BodyParams;
8402+
SourceLoc asyncLoc;
8403+
bool reasync;
8404+
SourceLoc throwsLoc;
8405+
bool rethrows;
8406+
Status |= parseFunctionSignature(DeclBaseName::createConstructor(), FullName,
8407+
BodyParams,
8408+
DefaultArgs,
8409+
asyncLoc, reasync,
8410+
throwsLoc, rethrows,
8411+
FuncRetTy);
84058412
if (Status.hasCodeCompletion() && !CodeCompletion) {
84068413
// Trigger delayed parsing, no need to continue.
84078414
return Status;
@@ -8413,17 +8420,23 @@ Parser::parseDeclInit(ParseDeclOptions Flags, DeclAttributes &Attributes) {
84138420
return nullptr;
84148421
}
84158422

8416-
// Parse 'async' / 'reasync' / 'throws' / 'rethrows'.
8417-
SourceLoc asyncLoc;
8418-
bool reasync = false;
8419-
SourceLoc throwsLoc;
8420-
bool rethrows = false;
8421-
Status |= parseEffectsSpecifiers(SourceLoc(),
8422-
asyncLoc, &reasync,
8423-
throwsLoc, &rethrows);
8424-
if (Status.hasCodeCompletion() && !CodeCompletion) {
8425-
// Trigger delayed parsing, no need to continue.
8426-
return Status;
8423+
// If there was an 'async' modifier, put it in the right place for an
8424+
// initializer.
8425+
bool isAsync = asyncLoc.isValid();
8426+
if (auto asyncAttr = Attributes.getAttribute<AsyncAttr>()) {
8427+
SourceLoc insertLoc = Lexer::getLocForEndOfToken(
8428+
SourceMgr, BodyParams->getRParenLoc());
8429+
8430+
diagnose(asyncAttr->getLocation(), diag::async_func_modifier)
8431+
.fixItRemove(asyncAttr->getRange())
8432+
.fixItInsert(insertLoc, " async");
8433+
asyncAttr->setInvalid();
8434+
isAsync = true;
8435+
}
8436+
8437+
if (FuncRetTy) {
8438+
diagnose(FuncRetTy->getStartLoc(), diag::initializer_result_type)
8439+
.fixItRemove(FuncRetTy->getSourceRange());
84278440
}
84288441

84298442
if (reasync) {
@@ -8435,12 +8448,11 @@ Parser::parseDeclInit(ParseDeclOptions Flags, DeclAttributes &Attributes) {
84358448

84368449
diagnoseWhereClauseInGenericParamList(GenericParams);
84378450

8438-
DeclName FullName(Context, DeclBaseName::createConstructor(), namePieces);
84398451
auto *CD = new (Context) ConstructorDecl(FullName, ConstructorLoc,
84408452
Failable, FailabilityLoc,
8441-
asyncLoc.isValid(), asyncLoc,
8453+
isAsync, asyncLoc,
84428454
throwsLoc.isValid(), throwsLoc,
8443-
Params.get(), GenericParams,
8455+
BodyParams, GenericParams,
84448456
CurDeclContext);
84458457
CD->setImplicitlyUnwrappedOptional(IUO);
84468458
CD->getAttrs() = Attributes;
@@ -8466,7 +8478,7 @@ Parser::parseDeclInit(ParseDeclOptions Flags, DeclAttributes &Attributes) {
84668478
CodeCompletion->setParsedDecl(CD);
84678479
}
84688480

8469-
if (ConstructorsNotAllowed || Params.isParseErrorOrHasCompletion()) {
8481+
if (ConstructorsNotAllowed) {
84708482
// Tell the type checker not to touch this constructor.
84718483
CD->setInvalid();
84728484
}

lib/Parse/ParsePattern.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ Parser::parseFunctionArguments(SmallVectorImpl<Identifier> &NamePieces,
863863
///
864864
/// Note that this leaves retType as null if unspecified.
865865
ParserStatus
866-
Parser::parseFunctionSignature(Identifier SimpleName,
866+
Parser::parseFunctionSignature(DeclBaseName SimpleName,
867867
DeclName &FullName,
868868
ParameterList *&bodyParams,
869869
DefaultArgumentInfo &defaultArgs,
@@ -876,8 +876,11 @@ Parser::parseFunctionSignature(Identifier SimpleName,
876876
SmallVector<Identifier, 4> NamePieces;
877877
ParserStatus Status;
878878

879-
ParameterContextKind paramContext = SimpleName.isOperator() ?
880-
ParameterContextKind::Operator : ParameterContextKind::Function;
879+
ParameterContextKind paramContext = SimpleName.isOperator()
880+
? ParameterContextKind::Operator
881+
: (SimpleName == DeclBaseName::createConstructor()
882+
? ParameterContextKind::Initializer
883+
: ParameterContextKind::Function);
881884
Status |= parseFunctionArguments(NamePieces, bodyParams, paramContext,
882885
defaultArgs);
883886
FullName = DeclName(Context, SimpleName, NamePieces);

0 commit comments

Comments
 (0)