Skip to content

Commit 4fc2333

Browse files
authored
Merge pull request #37986 from DougGregor/parse-closure-attributes-and-captures
[Parser] Allow closures with custom attributes and capture lists.
2 parents bffba72 + c737327 commit 4fc2333

File tree

6 files changed

+33
-19
lines changed

6 files changed

+33
-19
lines changed

include/swift/Parse/Parser.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,15 +1218,25 @@ class Parser {
12181218

12191219
//===--------------------------------------------------------------------===//
12201220
// Type Parsing
1221-
1221+
1222+
enum class ParseTypeReason {
1223+
/// Any type parsing context.
1224+
Unspecified,
1225+
1226+
/// Whether the type is for a closure attribute.
1227+
CustomAttribute,
1228+
};
1229+
12221230
ParserResult<TypeRepr> parseType();
1223-
ParserResult<TypeRepr> parseType(Diag<> MessageID,
1224-
bool IsSILFuncDecl = false);
1231+
ParserResult<TypeRepr> parseType(
1232+
Diag<> MessageID,
1233+
ParseTypeReason reason = ParseTypeReason::Unspecified);
12251234

12261235
ParserResult<TypeRepr>
1227-
parseTypeSimpleOrComposition(Diag<> MessageID);
1236+
parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason);
12281237

1229-
ParserResult<TypeRepr> parseTypeSimple(Diag<> MessageID);
1238+
ParserResult<TypeRepr> parseTypeSimple(
1239+
Diag<> MessageID, ParseTypeReason reason);
12301240

12311241
/// Parse layout constraint.
12321242
LayoutConstraint parseLayoutConstraint(Identifier LayoutConstraintID);

lib/Parse/ParseDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2821,7 +2821,7 @@ ParserResult<CustomAttr> Parser::parseCustomAttribute(
28212821
SyntaxContext->setCreateSyntax(SyntaxKind::CustomAttribute);
28222822

28232823
// Parse a custom attribute.
2824-
auto type = parseType(diag::expected_type);
2824+
auto type = parseType(diag::expected_type, ParseTypeReason::CustomAttribute);
28252825
if (type.hasCodeCompletion() || type.isNull()) {
28262826
if (Tok.is(tok::l_paren) && isCustomAttributeArgument())
28272827
skipSingle();

lib/Parse/ParsePattern.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
374374
}
375375

376376
if (isBareType && paramContext == ParameterContextKind::EnumElement) {
377-
auto type = parseType(diag::expected_parameter_type, false);
377+
auto type = parseType(diag::expected_parameter_type);
378378
status |= type;
379379
param.Type = type.getPtrOrNull();
380380
param.FirstName = Identifier();
@@ -389,7 +389,7 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
389389
// the user is about to type the parameter label and we shouldn't
390390
// suggest types.
391391
SourceLoc typeStartLoc = Tok.getLoc();
392-
auto type = parseType(diag::expected_parameter_type, false);
392+
auto type = parseType(diag::expected_parameter_type);
393393
status |= type;
394394
param.Type = type.getPtrOrNull();
395395

lib/Parse/ParseType.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,8 @@ LayoutConstraint Parser::parseLayoutConstraint(Identifier LayoutConstraintID) {
157157
/// type-simple '!'
158158
/// type-collection
159159
/// type-array
160-
ParserResult<TypeRepr> Parser::parseTypeSimple(Diag<> MessageID) {
160+
ParserResult<TypeRepr> Parser::parseTypeSimple(
161+
Diag<> MessageID, ParseTypeReason reason) {
161162
ParserResult<TypeRepr> ty;
162163

163164
if (Tok.is(tok::kw_inout) ||
@@ -242,7 +243,7 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(Diag<> MessageID) {
242243
continue;
243244
}
244245
// Parse legacy array types for migration.
245-
if (Tok.is(tok::l_square)) {
246+
if (Tok.is(tok::l_square) && reason != ParseTypeReason::CustomAttribute) {
246247
ty = parseTypeArray(ty);
247248
continue;
248249
}
@@ -329,8 +330,8 @@ ParserResult<TypeRepr> Parser::parseSILBoxType(GenericParamList *generics,
329330
/// type-function:
330331
/// type-composition 'async'? 'throws'? '->' type
331332
///
332-
ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
333-
bool IsSILFuncDecl) {
333+
ParserResult<TypeRepr> Parser::parseType(
334+
Diag<> MessageID, ParseTypeReason reason) {
334335
// Start a context for creating type syntax.
335336
SyntaxParsingContext TypeParsingContext(SyntaxContext,
336337
SyntaxContextKind::Type);
@@ -369,7 +370,7 @@ ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
369370
return parseSILBoxType(generics, attrs);
370371
}
371372

372-
ParserResult<TypeRepr> ty = parseTypeSimpleOrComposition(MessageID);
373+
ParserResult<TypeRepr> ty = parseTypeSimpleOrComposition(MessageID, reason);
373374
status |= ParserStatus(ty);
374375
if (ty.isNull())
375376
return status;
@@ -762,7 +763,7 @@ Parser::parseTypeIdentifier(bool isParsingQualifiedDeclBaseType) {
762763
/// 'some'? type-simple
763764
/// type-composition '&' type-simple
764765
ParserResult<TypeRepr>
765-
Parser::parseTypeSimpleOrComposition(Diag<> MessageID) {
766+
Parser::parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason) {
766767
SyntaxParsingContext SomeTypeContext(SyntaxContext, SyntaxKind::SomeType);
767768
// Check for the opaque modifier.
768769
// This is only semantically allowed in certain contexts, but we parse it
@@ -786,7 +787,7 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID) {
786787

787788
SyntaxParsingContext CompositionContext(SyntaxContext, SyntaxContextKind::Type);
788789
// Parse the first type
789-
ParserResult<TypeRepr> FirstType = parseTypeSimple(MessageID);
790+
ParserResult<TypeRepr> FirstType = parseTypeSimple(MessageID, reason);
790791
if (FirstType.isNull())
791792
return FirstType;
792793
if (!Tok.isContextualPunctuator("&")) {
@@ -844,7 +845,7 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID) {
844845

845846
// Parse next type.
846847
ParserResult<TypeRepr> ty =
847-
parseTypeSimple(diag::expected_identifier_for_type);
848+
parseTypeSimple(diag::expected_identifier_for_type, reason);
848849
if (ty.hasCodeCompletion())
849850
return makeParserCodeCompletionResult<TypeRepr>();
850851
Status |= ty;

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,8 +1259,7 @@ bool SILParser::parseSILType(SILType &Result,
12591259
TypeAttributes::Convention::makeSwiftConvention("thin");
12601260
}
12611261

1262-
ParserResult<TypeRepr> TyR = P.parseType(diag::expected_sil_type,
1263-
/*isSILFuncDecl*/ IsFuncDecl);
1262+
ParserResult<TypeRepr> TyR = P.parseType(diag::expected_sil_type);
12641263

12651264
if (TyR.isNull())
12661265
return true;

test/Concurrency/global_actor_function_types.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func someSlowOperation() async -> Int { 5 }
3333

3434
func acceptOnSomeGlobalActor<T>(_: @SomeGlobalActor () -> T) { }
3535

36-
func testClosures() async {
36+
func testClosures(i: Int) async {
3737
// Global actors on synchronous closures become part of the type
3838
let cl1 = { @SomeGlobalActor in
3939
onSomeGlobalActor()
@@ -46,6 +46,10 @@ func testClosures() async {
4646
}
4747
let _: Double = cl2 // expected-error{{cannot convert value of type '() async -> Int' to specified type 'Double'}}
4848

49+
let cl3 = { @SomeGlobalActor [i] in
50+
print(i + onSomeGlobalActor())
51+
}
52+
4953
// okay to be explicit
5054
acceptOnSomeGlobalActor { @SomeGlobalActor in
5155
onSomeGlobalActor()

0 commit comments

Comments
 (0)