@@ -186,7 +186,7 @@ extension Parser {
186186 var keepGoing : RawTokenSyntax ? = nil
187187 var loopProgress = LoopProgressCondition ( )
188188 repeat {
189- let condition = self . parseConditionElement ( )
189+ let condition = self . parseConditionElement ( lastBindingKind : elements . last ? . condition . as ( RawOptionalBindingConditionSyntax . self ) ? . bindingKeyword )
190190 let unexpectedBeforeKeepGoing : RawUnexpectedNodesSyntax ?
191191 keepGoing = self . consume ( if: . comma)
192192 if keepGoing == nil , let andOperator = self . consumeIfContextualPunctuator ( " && " ) {
@@ -219,15 +219,15 @@ extension Parser {
219219 /// optional-binding-condition → 'let' pattern initializer? | 'var' pattern initializer? |
220220 /// 'inout' pattern initializer?
221221 @_spi ( RawSyntax)
222- public mutating func parseConditionElement( ) -> RawConditionElementSyntax . Condition {
222+ public mutating func parseConditionElement( lastBindingKind : RawTokenSyntax ? ) -> RawConditionElementSyntax . Condition {
223223 // Parse a leading #available/#unavailable condition if present.
224224 if self . at ( . poundAvailableKeyword, . poundUnavailableKeyword) {
225225 return self . parsePoundAvailableConditionElement ( )
226226 }
227227
228228 // Parse the basic expression case. If we have a leading let, var, inout,
229229 // borrow, case keyword or an assignment, then we know this is a binding.
230- guard self . at ( . keyword( . let) , . keyword( . var) , . keyword( . case) ) || self . at ( . keyword( . inout) ) else {
230+ guard self . at ( . keyword( . let) , . keyword( . var) , . keyword( . case) ) || self . at ( . keyword( . inout) ) || ( lastBindingKind != nil && self . peek ( ) . rawTokenKind == . equal ) else {
231231 // If we lack it, then this is theoretically a boolean condition.
232232 // However, we also need to handle migrating from Swift 2 syntax, in
233233 // which a comma followed by an expression could actually be a pattern
@@ -244,20 +244,28 @@ extension Parser {
244244 }
245245
246246 // We're parsing a conditional binding.
247- precondition ( self . at ( . keyword( . let) , . keyword( . var) ) || self . at ( . keyword( . inout) , . keyword( . case) ) )
248247 enum BindingKind {
249248 case pattern( RawTokenSyntax , RawPatternSyntax )
250- case optional( RawTokenSyntax , RawPatternSyntax )
249+ case optional( RawUnexpectedNodesSyntax ? , RawTokenSyntax , RawPatternSyntax )
251250 }
252251
253252 let kind : BindingKind
254253 if let caseKeyword = self . consume ( if: . keyword( . case) ) {
255254 let pattern = self . parseMatchingPattern ( context: . matching)
256255 kind = . pattern( caseKeyword, pattern)
257256 } else {
258- let letOrVar = self . consumeAnyToken ( )
257+ let unexpectedBeforeBindingKeyword : RawUnexpectedNodesSyntax ?
258+ let letOrVar : RawTokenSyntax
259+
260+ if self . at ( . identifier) , let lastBindingKind = lastBindingKind {
261+ ( unexpectedBeforeBindingKeyword, letOrVar) = self . expect ( . keyword( . let) , . keyword( . var) , default: . keyword( Keyword ( lastBindingKind. tokenText) ?? . let) )
262+ } else {
263+ letOrVar = self . consume ( if: TokenSpec . keyword ( . let) , . keyword( . var) ) ?? self . missingToken ( . let)
264+ unexpectedBeforeBindingKeyword = nil
265+ }
266+
259267 let pattern = self . parseMatchingPattern ( context: . bindingIntroducer)
260- kind = . optional( letOrVar, pattern)
268+ kind = . optional( unexpectedBeforeBindingKeyword , letOrVar, pattern)
261269 }
262270
263271 // Now parse an optional type annotation.
@@ -289,9 +297,10 @@ extension Parser {
289297 }
290298
291299 switch kind {
292- case let . optional( bindingKeyword, pattern) :
300+ case let . optional( unexpectedBeforeBindingKeyword , bindingKeyword, pattern) :
293301 return . optionalBinding(
294302 RawOptionalBindingConditionSyntax (
303+ unexpectedBeforeBindingKeyword,
295304 bindingKeyword: bindingKeyword,
296305 pattern: pattern,
297306 typeAnnotation: annotation,
0 commit comments