Skip to content

Commit ea63030

Browse files
committed
Add trailing comma support in cases missing from Swift 6.1
1 parent 749e9ee commit ea63030

16 files changed

+152
-31
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,11 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
535535
// Parse the trailing comma
536536
if (consumeIf(tok::comma)) {
537537
HasUpcomingEntry = true;
538+
539+
// If this is a trailing comma then there are no more entries
540+
if (Tok.is(tok::r_paren)) {
541+
break;
542+
}
538543
} else {
539544
HasUpcomingEntry = false;
540545
}
@@ -1008,6 +1013,11 @@ Parser::parseStorageRestrictionsAttribute(SourceLoc AtLoc, SourceLoc Loc) {
10081013

10091014
// Parse the comma, if the list continues.
10101015
hasNextProperty = consumeIf(tok::comma);
1016+
1017+
// If this was a trailing comma, the list is complete.
1018+
if (Tok.is(tok::r_paren)) {
1019+
break;
1020+
}
10111021
} while (hasNextProperty);
10121022

10131023
return status;
@@ -2015,7 +2025,7 @@ bool Parser::parseBackDeployedAttribute(DeclAttributes &Attributes,
20152025
do {
20162026
Result = parseListItem(
20172027
Status, tok::r_paren, LeftLoc, RightLoc,
2018-
/*AllowSepAfterLast=*/false, [&]() -> ParserStatus {
2028+
/*AllowSepAfterLast=*/true, [&]() -> ParserStatus {
20192029
return parsePlatformVersionInList(AtAttrName, PlatformAndVersions,
20202030
ParsedUnrecognizedPlatformName);
20212031
});
@@ -2137,7 +2147,7 @@ Parser::parseAttributeArguments(SourceLoc attrLoc, StringRef attrName,
21372147
}
21382148

21392149
return parseList(tok::r_paren, parensRange.Start, parensRange.End,
2140-
/*allow sep after last*/ true,
2150+
/*AllowSepAfterLast=*/true,
21412151
{diag::attr_expected_rparen, {attrName, isModifier}},
21422152
parseArg);
21432153
}
@@ -2257,7 +2267,7 @@ Parser::parseMacroRoleAttribute(
22572267
SmallVector<Expr *, 2> conformances;
22582268
auto argumentsStatus = parseList(
22592269
tok::r_paren, lParenLoc, rParenLoc,
2260-
/*AllowSepAfterLast=*/false, diag::expected_rparen_expr_list, [&] {
2270+
/*AllowSepAfterLast=*/true, diag::expected_rparen_expr_list, [&] {
22612271
ParserStatus status;
22622272

22632273
if (consumeIf(tok::code_complete)) {
@@ -3245,7 +3255,8 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
32453255
StringRef AttrName = "@_originallyDefinedIn";
32463256
bool SuppressLaterDiags = false;
32473257
bool ParsedUnrecognizedPlatformName = false;
3248-
if (parseList(tok::r_paren, LeftLoc, RightLoc, false,
3258+
if (parseList(tok::r_paren, LeftLoc, RightLoc,
3259+
/*AllowSepAfterLast=*/true,
32493260
diag::originally_defined_in_missing_rparen,
32503261
[&]() -> ParserStatus {
32513262
SWIFT_DEFER {
@@ -4978,7 +4989,7 @@ ParserResult<LifetimeEntry> Parser::parseLifetimeEntry(SourceLoc loc) {
49784989
SourceLoc rParenLoc;
49794990
bool foundParamId = false;
49804991
status = parseList(
4981-
tok::r_paren, lParenLoc, rParenLoc, /*AllowSepAfterLast*/ false,
4992+
tok::r_paren, lParenLoc, rParenLoc, /*AllowSepAfterLast=*/true,
49824993
diag::expected_rparen_after_lifetime_dependence, [&]() -> ParserStatus {
49834994
ParserStatus listStatus;
49844995
foundParamId = true;
@@ -9524,6 +9535,11 @@ ParserStatus Parser::parsePrimaryAssociatedTypeList(
95249535

95259536
// Parse the comma, if the list continues.
95269537
HasNextParam = consumeIf(tok::comma);
9538+
9539+
// The list ends if we find a trailing comma
9540+
if (startsWithGreater(Tok)) {
9541+
break;
9542+
}
95279543
} while (HasNextParam);
95289544

95299545
return Result;

lib/Parse/ParseStmt.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,8 +1445,8 @@ Parser::parseAvailabilitySpecList(SmallVectorImpl<AvailabilitySpec *> &Specs,
14451445
consumeToken();
14461446
Status.setIsParseError();
14471447
} else if (consumeIf(tok::comma)) {
1448-
// End of unavailable spec list with a trailing comma.
1449-
if (Source == AvailabilitySpecSource::Unavailable && Tok.is(tok::r_paren)) {
1448+
// End of spec list with a trailing comma.
1449+
if (Tok.is(tok::r_paren)) {
14501450
break;
14511451
}
14521452
// There is more to parse in this list.

lib/Parse/ParseType.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(
194194
SourceLoc rbLoc;
195195
SmallVector<TypeRepr *, 8> elements;
196196
auto status = parseList(tok::r_brace, lbLoc, rbLoc,
197-
/*AllowSepAfterLast=*/false,
197+
/*AllowSepAfterLast=*/true,
198198
diag::expected_rbrace_pack_type_list,
199199
[&] () -> ParserStatus {
200200
auto element = parseType(diag::expected_type);
@@ -739,9 +739,13 @@ ParserStatus Parser::parseGenericArguments(SmallVectorImpl<TypeRepr *> &Args,
739739
}
740740

741741
Args.push_back(Ty.get());
742-
// Parse the comma, if the list continues.
742+
// Parse the comma, if the list continues
743743
if (!consumeIf(tok::comma))
744744
break;
745+
746+
// If the comma was a trailing comma, finish parsing the list of types
747+
if (startsWithGreater(Tok))
748+
break;
745749
}
746750
}
747751

@@ -1161,7 +1165,7 @@ ParserResult<TypeRepr> Parser::parseTypeTupleBody() {
11611165
SmallVector<TupleTypeReprElement, 8> ElementsR;
11621166

11631167
ParserStatus Status = parseList(tok::r_paren, LPLoc, RPLoc,
1164-
/*AllowSepAfterLast=*/false,
1168+
/*AllowSepAfterLast=*/true,
11651169
diag::expected_rparen_tuple_type_list,
11661170
[&] () -> ParserStatus {
11671171
TupleTypeReprElement element;

test/ASTGen/availability.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,22 @@ func testSwift4OrLater() {}
3030
@available(macOS 12, iOS 13.1, *)
3131
func testShorthandMulti() {}
3232

33+
@available(macOS 12, iOS 13.1, *,)
34+
func testShorthandMulti2() {}
35+
3336
@available(macOS, unavailable)
3437
func testUnavailableMacOS() {}
3538

3639
@available(macOS, deprecated: 12.0.5, message: "whatever")
3740
func testDeprecaed12MacOS() {}
3841

42+
@available(
43+
macOS,
44+
deprecated: 12.0.5,
45+
message: "whatever",
46+
)
47+
func testDeprecaed12MacOS2() {}
48+
3949
@available(_iOS53Aligned, *)
4050
func testMacroNameOnly() {}
4151

@@ -48,10 +58,27 @@ func testSpecialize<T>(arg: T) -> T {}
4858
@backDeployed(before: _iOS53Aligned)
4959
public func testBackDeployed() {}
5060

61+
@backDeployed(
62+
before: _iOS53Aligned,
63+
)
64+
public func testBackDeployed2() {}
65+
5166
@available(macOS 10, iOS 12, *)
5267
@_originallyDefinedIn(module: "OriginalModule", macOS 12.0, iOS 23.2)
5368
public func testOriginallyDefinedIn() {}
5469

70+
@available(
71+
macOS 10,
72+
iOS 12,
73+
*,
74+
)
75+
@_originallyDefinedIn(
76+
module: "OriginalModule",
77+
macOS 12.0,
78+
iOS 23.2,
79+
)
80+
public func testOriginallyDefinedIn2() {}
81+
5582

5683
func testPoundIf() {
5784
if #available(_myProject 2.5, *) {

test/ASTGen/macros.swift

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ struct Outer {
1818
#anonymousTypes { "test" }
1919
}
2020

21-
@attached(extension, conformances: P1, P2)
21+
@attached(
22+
extension,
23+
conformances: P1, P2,
24+
)
2225
macro AddAllConformances() = #externalMacro(module: "MacroDefinition", type: "AddAllConformancesMacro")
2326

2427
protocol P1 {}
@@ -39,6 +42,13 @@ protocol DefaultInit {
3942
@attached(extension, conformances: Equatable, names: named(==))
4043
macro Equatable() = #externalMacro(module: "MacroDefinition", type: "EquatableViaMembersMacro")
4144

45+
@attached(
46+
extension,
47+
conformances: Equatable,
48+
names: named(==),
49+
)
50+
macro Equatable2() = #externalMacro(module: "MacroDefinition", type: "EquatableViaMembersMacro")
51+
4252
@propertyWrapper
4353
struct NotEquatable<T> {
4454
var wrappedValue: T
@@ -112,10 +122,17 @@ func remoteCall<Result: ConjureRemoteValue>(function: String, arguments: [String
112122
func f(a: Int, b: String) async throws -> String
113123

114124
@freestanding(declaration, names: arbitrary) macro bitwidthNumberedStructs(_ baseName: String) = #externalMacro(module: "MacroDefinition", type: "DefineBitwidthNumberedStructsMacro")
125+
115126
struct TestArbitrary {
116127
#bitwidthNumberedStructs("MyIntOne")
117128
}
118129
130+
@freestanding(
131+
declaration,
132+
names: arbitrary,
133+
)
134+
macro bitwidthNumberedStructs2(_ baseName: String) = #externalMacro(module: "MacroDefinition", type: "DefineBitwidthNumberedStructsMacro")
135+
119136
// Stored properties generated by a peer macro
120137
@attached(accessor)
121138
@attached(peer, names: prefixed(_))
@@ -151,5 +168,8 @@ protocol MyType {
151168
associatedtype Value
152169
associatedtype Entity
153170
}
154-
@attached(peer, names: named(bar))
171+
@attached(
172+
peer,
173+
names: named(bar),
174+
)
155175
macro Wrapper<Value>(get: (Value.Entity) async throws -> Value.Value) = #externalMacro(module: "MacroDefinition", type: "WrapperMacro") where Value: MyType

test/Casting/ParameterizedExistentials.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ struct GenericHolder<T>: Holder {
4646
init(value: T) { self.value = value}
4747
}
4848

49-
protocol PairType<T, U> {
49+
protocol PairType<
50+
T,
51+
U,
52+
> {
5053
associatedtype T
5154
associatedtype U
5255

test/Parse/availability_query.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ if #available(OSX 51, iOS 8.0, *) {
9494
if #available(OSX 51, { // expected-error {{expected platform name}} // expected-error {{expected ')'}} expected-note {{to match this opening '('}}
9595
}
9696

97-
if #available(OSX 51,) { // expected-error {{expected platform name}}
97+
if #available(OSX 51,) { // expected-error {{must handle potential future platforms with '*'}}
9898
}
9999

100100
if #available(OSX 51, iOS { // expected-error {{expected ')'}} expected-note {{to match this opening '('}}

test/Parse/trailing-comma.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,20 +66,20 @@ struct S {
6666
6767
if #unavailable(iOS 15, watchOS 9,) { }
6868
69-
if #available(iOS 15,) { } // expected-error {{expected platform name}}
69+
if #available(iOS 15,) { }
7070
7171
// Built-in Attributes
7272
73-
@attached(extension, conformances: OptionSet,) // expected-error {{unexpected ',' separator}}
73+
@attached(extension, conformances: OptionSet,)
7474
macro OptionSet<RawType>() = #externalMacro(module: "SwiftMacros", type: "OptionSetMacro")
7575

7676
@inline(never,) // expected-error {{expected declaration}} expected-error {{expected ')' in 'inline' attribute}}
7777
func foo() { }
7878

79-
@available(iOS 15,) // expected-error {{expected platform name}} expected-error {{expected declaration}}
79+
@available(iOS 15,)
8080
func foo() { }
8181

82-
@backDeployed(before: SwiftStdlib 6.0,) // expected-error {{unexpected ',' separator}}
82+
@backDeployed(before: SwiftStdlib 6.0,)
8383
func foo() { }
8484

8585
struct Foo {
@@ -88,7 +88,7 @@ struct Foo {
8888
var y: Int
8989

9090
var value: (Int, Int) {
91-
@storageRestrictions(initializes: x, y,) // expected-error {{expected property name in '@storageRestrictions' list}}
91+
@storageRestrictions(initializes: x, y,)
9292
init(initialValue) {
9393
self.x = initialValue.0
9494
self.y = initialValue.1
@@ -98,7 +98,7 @@ struct Foo {
9898

9999
}
100100

101-
func f(in: @differentiable(reverse,) (Int) -> Int) { } // expected-warning {{@differentiable' has been renamed to '@differentiable(reverse)' and will be removed in the next release}} expected-error {{unexpected ',' separator}} expected-error {{expected ',' separator}} expected-error {{unnamed parameters must be written with the empty name '_'}}
101+
func f(in: @differentiable(reverse,) (Int) -> Int) { } // expected-warning {{@differentiable' has been renamed to '@differentiable(reverse)' and will be removed in the next release}} expected-error {{expected ',' separator}} expected-error {{unnamed parameters must be written with the empty name '_'}}
102102

103103
@derivative(of: Self.other,) // expected-error {{unexpected ',' separator}}
104104
func foo() {}

test/attr/Inputs/SymbolMove/LowLevel.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,16 @@ extension Box {
3030
public func shape() -> String { return "round"}
3131
}
3232

33-
@available(OSX 10.7, iOS 7.0, *)
34-
@_originallyDefinedIn(module: "HighLevel", OSX 10.9, iOS 13.0)
33+
@available(
34+
OSX 10.7,
35+
iOS 7.0,
36+
*,
37+
)
38+
@_originallyDefinedIn(
39+
module: "HighLevel",
40+
OSX 10.9,
41+
iOS 13.0,
42+
)
3543
public struct Candy {
3644
public var kind = "candy"
3745
public init() {}

test/attr/attr_availability_noasync.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,19 @@
66
@available(*, noasync)
77
func basicNoAsync() { }
88

9+
@available(*, noasync,)
10+
func basicNoAsync2() { }
11+
912
@available(*, noasync, message: "a message from the author")
1013
func messageNoAsync() { }
1114

15+
@available(
16+
*,
17+
noasync,
18+
message: "a message from the author",
19+
)
20+
func messageNoAsync2() { }
21+
1222
@available(*, noasync, renamed: "asyncReplacement()")
1323
func renamedNoAsync(_ completion: @escaping (Int) -> Void) -> Void { }
1424

test/attr/attr_availability_watchos.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,12 @@ if #available(iOS 9.3, *) {
5858
// expected-note@-1 {{add 'if #available' version check}}
5959
}
6060

61-
if #available(iOS 9.3, watchOS 2.1, *) {
62-
functionIntroducedOnwatchOS2_2() // expected-error {{'functionIntroducedOnwatchOS2_2()' is only available in watchOS 2.2 or newer}} {{-1:32-35=2.2}}
61+
if #available(
62+
iOS 9.3,
63+
watchOS 2.1,
64+
*,
65+
) {
66+
functionIntroducedOnwatchOS2_2() // expected-error {{'functionIntroducedOnwatchOS2_2()' is only available in watchOS 2.2 or newer}} {{63:11-14=2.2}}
6367
}
6468

6569
if #available(iOS 9.1, watchOS 2.2, *) {

test/attr/attr_backDeployed.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,8 @@ public func missingVersionFunc3() {}
394394
@backDeployed(before: macOS 0) // expected-warning {{expected version number in '@backDeployed' attribute; this is an error in the Swift 6 language mode}}
395395
public func missingVersionFunc4() {}
396396

397-
@backDeployed(before: macOS 12.0, iOS 15.0,) // expected-error {{unexpected ',' separator}}
398-
public func unexpectedSeparatorFunc() {}
397+
@backDeployed(before: macOS 12.0, iOS 15.0,)
398+
public func trailingCommaFunc1() {}
399399

400400
@backDeployed(before: macOS 12.0.1) // expected-warning {{'@backDeployed' only uses major and minor version number}}
401401
public func patchVersionFunc() {}
@@ -440,8 +440,8 @@ public func missingColonAfterBeforeFunc() {}
440440
@backDeployed(before macOS 12.0) // expected-error {{expected ':' after 'before' in '@backDeployed' attribute}} {{21-21=:}}
441441
public func missingColonBetweenBeforeAndPlatformFunc() {}
442442

443-
@backDeployed(before: macOS 12.0,) // expected-error {{unexpected ',' separator}} {{33-34=}}
444-
public func unexpectedTrailingCommaFunc() {}
443+
@backDeployed(before: macOS 12.0,)
444+
public func trailingCommaFunc2() {}
445445

446446
@backDeployed(before: macOS 12.0,, iOS 15.0) // expected-error {{unexpected ',' separator}} {{34-35=}}
447447
public func extraCommaFunc() {}

test/attr/attr_inlinable_available.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,10 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
530530
_ = AtDeploymentTarget()
531531
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
532532

533-
if #available(macOS 11, *) {
533+
if #available(
534+
macOS 11,
535+
*,
536+
) {
534537
_ = AfterDeploymentTarget()
535538
}
536539
}
@@ -720,7 +723,7 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
720723
_ = AtDeploymentTarget()
721724
_ = AfterDeploymentTarget()
722725

723-
if #available(macOS 11, *) {
726+
if #available(macOS 11, *,) {
724727
_ = AfterDeploymentTarget()
725728
}
726729

0 commit comments

Comments
 (0)