Skip to content

Commit feb1787

Browse files
committed
[Parser] Allow closures with custom attributes and capture lists.
The parsing of Swift 1.0 beta-1 array syntax (e.g., `Int [something]`) was preventing closures with both a custom attribute (e.g., `@MainActor) and a capture list from parsing correctly. Don't parse that syntax within custom attributes. Fixes rdar://77303587.
1 parent 0887614 commit feb1787

File tree

6 files changed

+33
-21
lines changed

6 files changed

+33
-21
lines changed

include/swift/Parse/Parser.h

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

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

12171226
ParserResult<TypeRepr>
1218-
parseTypeSimpleOrComposition(Diag<> MessageID);
1227+
parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason);
12191228

1220-
ParserResult<TypeRepr> parseTypeSimple(Diag<> MessageID);
1229+
ParserResult<TypeRepr> parseTypeSimple(
1230+
Diag<> MessageID, ParseTypeReason reason);
12211231

12221232
/// Parse layout constraint.
12231233
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()

0 commit comments

Comments
 (0)