@@ -128,6 +128,13 @@ public enum EffectSpecifier: TokenSpecSet {
128128 case . throwsSpecifier( let underlyingKind) : return underlyingKind. spec
129129 }
130130 }
131+
132+ var isThrowsSpecifier : Bool {
133+ switch self {
134+ case . asyncSpecifier: return false
135+ case . throwsSpecifier: return true
136+ }
137+ }
131138}
132139
133140// MARK: - EffectSpecifiersTrait
@@ -153,10 +160,12 @@ protocol RawMisplacedEffectSpecifiersTrait {
153160
154161 var asyncSpecifier : RawTokenSyntax ? { get }
155162 var throwsSpecifier : RawTokenSyntax ? { get }
163+ var thrownError : RawThrownTypeClauseSyntax ? { get }
156164
157165 init (
158166 asyncSpecifier: RawTokenSyntax ? ,
159167 throwsSpecifier: RawTokenSyntax ? ,
168+ thrownError: RawThrownTypeClauseSyntax ? ,
160169 arena: __shared SyntaxArena
161170 )
162171
@@ -166,14 +175,17 @@ protocol RawMisplacedEffectSpecifiersTrait {
166175protocol RawEffectSpecifiersTrait : RawMisplacedEffectSpecifiersTrait {
167176 var unexpectedBeforeAsyncSpecifier : RawUnexpectedNodesSyntax ? { get }
168177 var unexpectedBetweenAsyncSpecifierAndThrowsSpecifier : RawUnexpectedNodesSyntax ? { get }
169- var unexpectedAfterThrowsSpecifier : RawUnexpectedNodesSyntax ? { get }
170-
178+ var unexpectedBetweenThrowsSpecifierAndThrownError : RawUnexpectedNodesSyntax ? { get }
179+ var thrownError : RawThrownTypeClauseSyntax ? { get }
180+ var unexpectedAfterThrownError : RawUnexpectedNodesSyntax ? { get }
171181 init (
172182 _ unexpectedBeforeAsyncSpecifier: RawUnexpectedNodesSyntax ? ,
173183 asyncSpecifier: RawTokenSyntax ? ,
174184 _ unexpectedBetweenAsyncSpecifierAndThrowsSpecifier: RawUnexpectedNodesSyntax ? ,
175185 throwsSpecifier: RawTokenSyntax ? ,
176- _ unexpectedAfterThrowsSpecifier: RawUnexpectedNodesSyntax ? ,
186+ _ unexpectedBetweenThrowsSpecifierAndThrownError: RawUnexpectedNodesSyntax ? ,
187+ thrownError: RawThrownTypeClauseSyntax ? ,
188+ _ unexpectedAfterThrownError: RawUnexpectedNodesSyntax ? ,
177189 arena: __shared SyntaxArena
178190 )
179191}
@@ -182,6 +194,7 @@ extension RawEffectSpecifiersTrait {
182194 init (
183195 asyncSpecifier: RawTokenSyntax ? ,
184196 throwsSpecifier: RawTokenSyntax ? ,
197+ thrownError: RawThrownTypeClauseSyntax ? ,
185198 arena: __shared SyntaxArena
186199 ) {
187200 self . init (
@@ -190,6 +203,8 @@ extension RawEffectSpecifiersTrait {
190203 nil ,
191204 throwsSpecifier: throwsSpecifier,
192205 nil ,
206+ thrownError: thrownError,
207+ nil ,
193208 arena: arena
194209 )
195210 }
@@ -200,7 +215,9 @@ extension RawEffectSpecifiersTrait {
200215 asyncSpecifier: self . asyncSpecifier ?? misplacedAsyncKeyword,
201216 self . unexpectedBetweenAsyncSpecifierAndThrowsSpecifier,
202217 throwsSpecifier: self . throwsSpecifier ?? misplacedThrowsKeyword,
203- self . unexpectedAfterThrowsSpecifier,
218+ self . unexpectedBetweenThrowsSpecifierAndThrownError,
219+ thrownError: thrownError,
220+ self . unexpectedAfterThrownError,
204221 arena: arena
205222 )
206223 }
@@ -521,10 +538,12 @@ extension RawDeinitializerEffectSpecifiersSyntax: RawMisplacedEffectSpecifiersTr
521538 }
522539
523540 var throwsSpecifier : RawTokenSyntax ? { nil }
541+ var thrownError : RawThrownTypeClauseSyntax ? { nil }
524542
525543 init (
526544 asyncSpecifier: RawTokenSyntax ? ,
527545 throwsSpecifier: RawTokenSyntax ? ,
546+ thrownError: RawThrownTypeClauseSyntax ? ,
528547 arena: __shared SwiftSyntax. SyntaxArena
529548 ) {
530549 // `throwsSpecifier` should never be present because `parseMisplacedEffectSpecifiers()` only creates missing tokens
@@ -577,12 +596,28 @@ extension TokenConsumer {
577596// MARK: - Parsing effect specifiers
578597
579598extension Parser {
599+ private mutating func parseThrownTypeClause( ) -> RawThrownTypeClauseSyntax {
600+ let ( unexpectedBeforeLeftParen, leftParen) = self . expect ( . leftParen)
601+ let type = self . parseType ( )
602+ let ( unexpectedBeforeRightParen, rightParen) = self . expect ( . rightParen)
603+ return RawThrownTypeClauseSyntax (
604+ unexpectedBeforeLeftParen,
605+ leftParen: leftParen,
606+ type: type,
607+ unexpectedBeforeRightParen,
608+ rightParen: rightParen,
609+ arena: self . arena
610+ )
611+ }
612+
580613 private mutating func parseEffectSpecifiers< S: RawEffectSpecifiersTrait > ( _: S . Type ) -> S ? {
581614 var unexpectedBeforeAsync : [ RawSyntax ] = [ ]
582615 var asyncKeyword : RawTokenSyntax ? = nil
583616 var unexpectedBeforeThrows : [ RawSyntax ] = [ ]
584617 var throwsKeyword : RawTokenSyntax ?
585- var unexpectedAfterThrows : [ RawSyntax ] = [ ]
618+ var thrownError : RawThrownTypeClauseSyntax ?
619+ var unexpectedAfterThrownError : [ RawSyntax ] = [ ]
620+
586621 while let misspelledAsync = self . consume ( ifAnyIn: S . MisspelledAsyncTokenKinds. self) {
587622 unexpectedBeforeAsync. append ( RawSyntax ( misspelledAsync) )
588623 if asyncKeyword == nil {
@@ -617,26 +652,32 @@ extension Parser {
617652 let ( unexpected, throwsKw) = self . eat ( handle)
618653 unexpectedBeforeThrows. append ( contentsOf: unexpected? . elements ?? [ ] )
619654 throwsKeyword = throwsKw
655+
656+ if self . at ( . leftParen) && experimentalFeatures. contains ( . typedThrows) {
657+ thrownError = parseThrownTypeClause ( )
658+ }
620659 }
621660
622- var unexpectedAfterThrowsLoopProgress = LoopProgressCondition ( )
623- while self . hasProgressed ( & unexpectedAfterThrowsLoopProgress ) {
661+ var unexpectedAfterThrownErrorLoopProgress = LoopProgressCondition ( )
662+ while self . hasProgressed ( & unexpectedAfterThrownErrorLoopProgress ) {
624663 if let ( _, handle, _) = self . at ( anyIn: S . MisspelledAsyncTokenKinds. self, or: S . CorrectAsyncTokenKinds. self) {
625664 let misspelledAsync = self . eat ( handle)
626- unexpectedAfterThrows . append ( RawSyntax ( misspelledAsync) )
665+ unexpectedAfterThrownError . append ( RawSyntax ( misspelledAsync) )
627666 if asyncKeyword == nil {
628667 // Handle `async` after `throws`
629668 asyncKeyword = missingToken ( . keyword( . async) )
630669 }
631670 } else if let ( _, handle, _) = self . at ( anyIn: S . MisspelledThrowsTokenKinds. self, or: S . CorrectThrowsTokenKinds. self) {
632671 let misspelledThrows = self . eat ( handle)
633- unexpectedAfterThrows . append ( RawSyntax ( misspelledThrows) )
672+ unexpectedAfterThrownError . append ( RawSyntax ( misspelledThrows) )
634673 } else {
635674 break
636675 }
637676 }
638677
639- if unexpectedBeforeAsync. isEmpty && asyncKeyword == nil && unexpectedBeforeThrows. isEmpty && throwsKeyword == nil && unexpectedAfterThrows. isEmpty {
678+ if unexpectedBeforeAsync. isEmpty && asyncKeyword == nil && unexpectedBeforeThrows. isEmpty && throwsKeyword == nil && thrownError == nil
679+ && unexpectedAfterThrownError. isEmpty
680+ {
640681 return nil
641682 }
642683
@@ -645,7 +686,9 @@ extension Parser {
645686 asyncSpecifier: asyncKeyword,
646687 RawUnexpectedNodesSyntax ( unexpectedBeforeThrows, arena: self . arena) ,
647688 throwsSpecifier: throwsKeyword,
648- RawUnexpectedNodesSyntax ( unexpectedAfterThrows, arena: self . arena) ,
689+ nil ,
690+ thrownError: thrownError,
691+ RawUnexpectedNodesSyntax ( unexpectedAfterThrownError, arena: self . arena) ,
649692 arena: self . arena
650693 )
651694 }
@@ -749,6 +792,7 @@ extension Parser {
749792 effectSpecifiers = S (
750793 asyncSpecifier: synthesizedAsync,
751794 throwsSpecifier: synthesizedThrows,
795+ thrownError: nil ,
752796 arena: self . arena
753797 )
754798 }
0 commit comments