Skip to content

Commit c737327

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 775bff0 commit c737327

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
@@ -1217,15 +1217,25 @@ class Parser {
12171217

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

12251234
ParserResult<TypeRepr>
1226-
parseTypeSimpleOrComposition(Diag<> MessageID);
1235+
parseTypeSimpleOrComposition(Diag<> MessageID, ParseTypeReason reason);
12271236

1228-
ParserResult<TypeRepr> parseTypeSimple(Diag<> MessageID);
1237+
ParserResult<TypeRepr> parseTypeSimple(
1238+
Diag<> MessageID, ParseTypeReason reason);
12291239

12301240
/// Parse layout constraint.
12311241
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)