@@ -691,11 +691,27 @@ extension Parser.Lookahead {
691691 var specifierProgress = LoopProgressCondition ( )
692692 // TODO: Can we model isolated/_const so that they're specified in both canParse* and parse*?
693693 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 ) ) ,
696696 self . hasProgressed ( & specifierProgress)
697697 {
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+ }
699715 }
700716
701717 var attributeProgress = LoopProgressCondition ( )
@@ -1059,10 +1075,24 @@ extension Parser {
10591075 private mutating func parseNonisolatedTypeSpecifier( ) -> RawTypeSpecifierListSyntax . Element {
10601076 let ( unexpectedBeforeNonisolatedKeyword, nonisolatedKeyword) = self . expect ( . keyword( . nonisolated) )
10611077
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)'
10661096 let argument = RawNonisolatedSpecifierArgumentSyntax (
10671097 leftParen: missingToken ( . leftParen) ,
10681098 nonsendingKeyword: missingToken ( . keyword( . nonsending) ) ,
@@ -1076,24 +1106,37 @@ extension Parser {
10761106 argument: argument,
10771107 arena: self . arena
10781108 )
1109+
10791110 return . nonisolatedTypeSpecifier( nonisolatedSpecifier)
10801111 }
10811112
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+
10841124 let nonisolatedSpecifier = RawNonisolatedTypeSpecifierSyntax (
10851125 unexpectedBeforeNonisolatedKeyword,
10861126 nonisolatedKeyword: nonisolatedKeyword,
1087- argument: nil ,
1127+ argument: argument ,
10881128 arena: self . arena
10891129 )
1130+
10901131 return . nonisolatedTypeSpecifier( nonisolatedSpecifier)
10911132 }
10921133
1134+ let ( unexpectedBeforeLeftParen, leftParen) = self . expect ( . leftParen)
10931135 let ( unexpectedBeforeModifier, modifier) = self . expect ( . keyword( . nonsending) )
10941136 let ( unexpectedBeforeRightParen, rightParen) = self . expect ( . rightParen)
10951137
10961138 let argument = RawNonisolatedSpecifierArgumentSyntax (
1139+ unexpectedBeforeLeftParen,
10971140 leftParen: leftParen,
10981141 unexpectedBeforeModifier,
10991142 nonsendingKeyword: modifier,
0 commit comments