diff --git a/Sources/SwiftParser/Types.swift b/Sources/SwiftParser/Types.swift index b569ad0ffbf..5bd1d0b55e9 100644 --- a/Sources/SwiftParser/Types.swift +++ b/Sources/SwiftParser/Types.swift @@ -1057,27 +1057,26 @@ extension Parser { return result } - if self.at(.rightSquareBracket) { - let (unexpectedBeforeRSquareBracket, rightSquareBracket) = self.expect(.rightSquareBracket) + // If the right square bracket is at a new line, we should just return the result + if let rightSquareBracket = self.consume(if: TokenSpec(.rightSquareBracket, allowAtStartOfLine: false)) { result = RawTypeSyntax( RawArrayTypeSyntax( leftSquareBracket: missingToken(.leftSquareBracket), elementType: result, - unexpectedBeforeRSquareBracket, rightSquareBracket: rightSquareBracket, arena: self.arena ) ) } else if self.at(.colon) { var lookahead = self.lookahead() - // We only want to continue with a dictionary if we can parse a colon and a simpletype. // Otherwise we can get a wrong diagnostic if we get a Python-style function declaration. - guard lookahead.consume(if: .colon) != nil && lookahead.canParseSimpleType() else { + guard lookahead.consume(if: .colon) != nil && lookahead.canParseSimpleType(), + let colon = self.consume(if: TokenSpec(.colon, allowAtStartOfLine: false)) + else { return result } - let (unexpectedBeforeColon, colon) = self.expect(.colon) let secondType = self.parseSimpleType() let rightSquareBracket = self.consume(if: .rightSquareBracket) ?? self.missingToken(.rightSquareBracket) @@ -1085,7 +1084,6 @@ extension Parser { RawDictionaryTypeSyntax( leftSquareBracket: self.missingToken(.leftSquareBracket), keyType: result, - unexpectedBeforeColon, colon: colon, valueType: secondType, rightSquareBracket: rightSquareBracket, diff --git a/Tests/SwiftParserTest/translated/RecoveryTests.swift b/Tests/SwiftParserTest/translated/RecoveryTests.swift index 3195dcaa3cc..0dda9d49fd7 100644 --- a/Tests/SwiftParserTest/translated/RecoveryTests.swift +++ b/Tests/SwiftParserTest/translated/RecoveryTests.swift @@ -1498,6 +1498,18 @@ final class RecoveryTests: XCTestCase { line: line ) } + + assertParse( + """ + let a8: Int + 1️⃣] + """, + diagnostics: [ + DiagnosticSpec( + message: "extraneous code ']' at top level" + ) + ] + ) } func testRecovery98b() { @@ -1527,7 +1539,7 @@ final class RecoveryTests: XCTestCase { let a2: 2️⃣String: Int] let a3: 3️⃣String: [Int]4️⃣ let a4: 5️⃣String: Int6️⃣ - let a4: 7️⃣String: Int]?? + let a5: 7️⃣String: Int]?? } """, diagnostics: [ @@ -1577,10 +1589,22 @@ final class RecoveryTests: XCTestCase { let a2: [String: Int] let a3: [String: [Int]] let a4: [String: Int] - let a4: [String: Int]?? + let a5: [String: Int]?? } """ ) + + assertParse( + """ + let a6: [Int: String] + 1️⃣] + """, + diagnostics: [ + DiagnosticSpec( + message: "extraneous code ']' at top level" + ) + ] + ) } func testRecovery100() {