@@ -691,11 +691,27 @@ extension Parser.Lookahead {
691
691
var specifierProgress = LoopProgressCondition ( )
692
692
// TODO: Can we model isolated/_const so that they're specified in both canParse* and parse*?
693
693
while canHaveParameterSpecifier,
694
- self . at ( anyIn: SimpleTypeSpecifierSyntax . SpecifierOptions. self) != nil || self . at ( . keyword ( . isolated ) )
695
- || self . at ( . keyword( . _const ) ) ,
694
+ self . at ( anyIn: SimpleTypeSpecifierSyntax . SpecifierOptions. self) != nil
695
+ || self . at ( . keyword( . nonisolated ) , . keyword ( . dependsOn ) ) ,
696
696
self . hasProgressed ( & specifierProgress)
697
697
{
698
- self . consumeAnyToken ( )
698
+ switch self . currentToken {
699
+ case . keyword( . nonisolated) , . keyword( . dependsOn) :
700
+ self . consumeAnyToken ( )
701
+
702
+ // The argument is missing but it still could be a valid modifier,
703
+ // i.e. `nonisolated` in an inheritance clause.
704
+ guard self . at ( . leftParen) else {
705
+ continue
706
+ }
707
+
708
+ if self . withLookahead ( { $0. atAttributeOrSpecifierArgument ( ) } ) {
709
+ skipSingle ( )
710
+ }
711
+
712
+ default :
713
+ self . consumeAnyToken ( )
714
+ }
699
715
}
700
716
701
717
var attributeProgress = LoopProgressCondition ( )
@@ -1059,10 +1075,24 @@ extension Parser {
1059
1075
private mutating func parseNonisolatedTypeSpecifier( ) -> RawTypeSpecifierListSyntax . Element {
1060
1076
let ( unexpectedBeforeNonisolatedKeyword, nonisolatedKeyword) = self . expect ( . keyword( . nonisolated) )
1061
1077
1062
- // Avoid being to greedy about `(` since this modifier should be associated with
1063
- // function types, it's possible that the argument is omitted and what follows
1064
- // is a function type i.e. `nonisolated () async -> Void`.
1065
- if self . at ( . leftParen) && !withLookahead( { $0. atAttributeOrSpecifierArgument ( ) } ) {
1078
+ // If the next token is not '(' this could mean two things:
1079
+ // - What follows is a type and we should allow it because
1080
+ // using `nonsisolated` without an argument is allowed in
1081
+ // an inheritance clause.
1082
+ // - The '(nonsending)' was omitted.
1083
+ if !self . at ( . leftParen) {
1084
+ // `nonisolated P<...>` is allowed in an inheritance clause.
1085
+ if withLookahead ( { $0. canParseTypeIdentifier ( ) } ) {
1086
+ let nonisolatedSpecifier = RawNonisolatedTypeSpecifierSyntax (
1087
+ unexpectedBeforeNonisolatedKeyword,
1088
+ nonisolatedKeyword: nonisolatedKeyword,
1089
+ argument: nil ,
1090
+ arena: self . arena
1091
+ )
1092
+ return . nonisolatedTypeSpecifier( nonisolatedSpecifier)
1093
+ }
1094
+
1095
+ // Otherwise require '(nonsending)'
1066
1096
let argument = RawNonisolatedSpecifierArgumentSyntax (
1067
1097
leftParen: missingToken ( . leftParen) ,
1068
1098
nonsendingKeyword: missingToken ( . keyword( . nonsending) ) ,
@@ -1076,24 +1106,37 @@ extension Parser {
1076
1106
argument: argument,
1077
1107
arena: self . arena
1078
1108
)
1109
+
1079
1110
return . nonisolatedTypeSpecifier( nonisolatedSpecifier)
1080
1111
}
1081
1112
1082
- // nonisolated without an argument is valid in some positions i.e. inheritance clause.
1083
- guard let leftParen = self . consume ( if: . leftParen) else {
1113
+ // Avoid being to greedy about `(` since this modifier should be associated with
1114
+ // function types, it's possible that the argument is omitted and what follows
1115
+ // is a function type i.e. `nonisolated () async -> Void`.
1116
+ if self . at ( . leftParen) && !withLookahead( { $0. atAttributeOrSpecifierArgument ( ) } ) {
1117
+ let argument = RawNonisolatedSpecifierArgumentSyntax (
1118
+ leftParen: missingToken ( . leftParen) ,
1119
+ nonsendingKeyword: missingToken ( . keyword( . nonsending) ) ,
1120
+ rightParen: missingToken ( . rightParen) ,
1121
+ arena: self . arena
1122
+ )
1123
+
1084
1124
let nonisolatedSpecifier = RawNonisolatedTypeSpecifierSyntax (
1085
1125
unexpectedBeforeNonisolatedKeyword,
1086
1126
nonisolatedKeyword: nonisolatedKeyword,
1087
- argument: nil ,
1127
+ argument: argument ,
1088
1128
arena: self . arena
1089
1129
)
1130
+
1090
1131
return . nonisolatedTypeSpecifier( nonisolatedSpecifier)
1091
1132
}
1092
1133
1134
+ let ( unexpectedBeforeLeftParen, leftParen) = self . expect ( . leftParen)
1093
1135
let ( unexpectedBeforeModifier, modifier) = self . expect ( . keyword( . nonsending) )
1094
1136
let ( unexpectedBeforeRightParen, rightParen) = self . expect ( . rightParen)
1095
1137
1096
1138
let argument = RawNonisolatedSpecifierArgumentSyntax (
1139
+ unexpectedBeforeLeftParen,
1097
1140
leftParen: leftParen,
1098
1141
unexpectedBeforeModifier,
1099
1142
nonsendingKeyword: modifier,
0 commit comments