Skip to content

Commit 4939e8f

Browse files
authored
Merge pull request #37987 from DougGregor/parse-closure-attributes-and-captures-5.5
[Parser] Allow closures with custom attributes and capture lists.
2 parents af463f9 + 959a41f commit 4939e8f

File tree

7 files changed

+34
-22
lines changed

7 files changed

+34
-22
lines changed

include/swift/Parse/Parser.h

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

12111211
//===--------------------------------------------------------------------===//
12121212
// Type Parsing
1213-
1213+
1214+
enum class ParseTypeReason {
1215+
/// Any type parsing context.
1216+
Unspecified,
1217+
1218+
/// Whether the type is for a closure attribute.
1219+
CustomAttribute,
1220+
};
1221+
12141222
ParserResult<TypeRepr> parseType();
1215-
ParserResult<TypeRepr> parseType(Diag<> MessageID,
1216-
bool IsSILFuncDecl = false);
1223+
ParserResult<TypeRepr> parseType(
1224+
Diag<> MessageID,
1225+
ParseTypeReason reason = ParseTypeReason::Unspecified);
12171226

12181227
ParserResult<TypeRepr>
1219-
parseTypeSimpleOrComposition(Diag<> MessageID);
1228+
parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason);
12201229

1221-
ParserResult<TypeRepr> parseTypeSimple(Diag<> MessageID);
1230+
ParserResult<TypeRepr> parseTypeSimple(
1231+
Diag<> MessageID, ParseTypeReason reason);
12221232

12231233
/// Parse layout constraint.
12241234
LayoutConstraint parseLayoutConstraint(Identifier LayoutConstraintID);

lib/Parse/ParseDecl.cpp

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

28622862
// Parse a custom attribute.
2863-
auto type = parseType(diag::expected_type);
2863+
auto type = parseType(diag::expected_type, ParseTypeReason::CustomAttribute);
28642864
if (type.hasCodeCompletion() || type.isNull()) {
28652865
if (Tok.is(tok::l_paren) && isCustomAttributeArgument())
28662866
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 & 10 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,10 +243,8 @@ 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.get());
247-
continue;
248-
}
249248
}
250249
break;
251250
}
@@ -329,8 +328,8 @@ ParserResult<TypeRepr> Parser::parseSILBoxType(GenericParamList *generics,
329328
/// type-function:
330329
/// type-composition 'async'? 'throws'? '->' type
331330
///
332-
ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
333-
bool IsSILFuncDecl) {
331+
ParserResult<TypeRepr> Parser::parseType(
332+
Diag<> MessageID, ParseTypeReason reason) {
334333
// Start a context for creating type syntax.
335334
SyntaxParsingContext TypeParsingContext(SyntaxContext,
336335
SyntaxContextKind::Type);
@@ -369,7 +368,7 @@ ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
369368
return parseSILBoxType(generics, attrs);
370369
}
371370

372-
ParserResult<TypeRepr> ty = parseTypeSimpleOrComposition(MessageID);
371+
ParserResult<TypeRepr> ty = parseTypeSimpleOrComposition(MessageID, reason);
373372
status |= ParserStatus(ty);
374373
if (ty.isNull())
375374
return status;
@@ -762,7 +761,7 @@ Parser::parseTypeIdentifier(bool isParsingQualifiedDeclBaseType) {
762761
/// 'some'? type-simple
763762
/// type-composition '&' type-simple
764763
ParserResult<TypeRepr>
765-
Parser::parseTypeSimpleOrComposition(Diag<> MessageID) {
764+
Parser::parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason) {
766765
SyntaxParsingContext SomeTypeContext(SyntaxContext, SyntaxKind::SomeType);
767766
// Check for the opaque modifier.
768767
// This is only semantically allowed in certain contexts, but we parse it
@@ -786,7 +785,7 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID) {
786785

787786
SyntaxParsingContext CompositionContext(SyntaxContext, SyntaxContextKind::Type);
788787
// Parse the first type
789-
ParserResult<TypeRepr> FirstType = parseTypeSimple(MessageID);
788+
ParserResult<TypeRepr> FirstType = parseTypeSimple(MessageID, reason);
790789
if (FirstType.isNull())
791790
return FirstType;
792791
if (!Tok.isContextualPunctuator("&")) {
@@ -844,7 +843,7 @@ Parser::parseTypeSimpleOrComposition(Diag<> MessageID) {
844843

845844
// Parse next type.
846845
ParserResult<TypeRepr> ty =
847-
parseTypeSimple(diag::expected_identifier_for_type);
846+
parseTypeSimple(diag::expected_identifier_for_type, reason);
848847
if (ty.hasCodeCompletion())
849848
return makeParserCodeCompletionResult<TypeRepr>();
850849
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()

test/Syntax/Outputs/round_trip_invalid.swift.withkinds

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// RUN: %swift-syntax-test -deserialize-raw-tree -input-source-filename %t.dump -output-filename %t
1010
// RUN: diff -u %s %t
1111

12-
let <PatternBinding><IdentifierPattern>strings</IdentifierPattern><TypeAnnotation>: [<SimpleTypeIdentifier>Strin</SimpleTypeIdentifier>[<UnresolvedPatternExpr><IdentifierPattern>g</IdentifierPattern></UnresolvedPatternExpr>]?</TypeAnnotation></PatternBinding></VariableDecl><FunctionDecl>
12+
let <PatternBinding><IdentifierPattern>strings</IdentifierPattern><TypeAnnotation>: [<SimpleTypeIdentifier>Strin</SimpleTypeIdentifier>[<UnresolvedPatternExpr><IdentifierPattern>g</IdentifierPattern></UnresolvedPatternExpr>]</TypeAnnotation></PatternBinding></VariableDecl>?<FunctionDecl>
1313

1414
// Function body without closing brace token.
1515
func foo<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<VariableDecl>

0 commit comments

Comments
 (0)