Skip to content

Commit 6a67add

Browse files
committed
Parse types with inverted constraints in expressions
Lookahead to determine when we are parsing a type within an expression context was failing to consider inverted constraints. Make sure we look past the `~` to an identifier. (cherry picked from commit f6fad30)
1 parent d12e37f commit 6a67add

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

Sources/SwiftParser/Expressions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ extension Parser {
523523
)
524524

525525
case (.any, _)?:
526-
if !atContextualExpressionModifier() {
526+
if !atContextualExpressionModifier() && !self.peek().isContextualPunctuator("~") {
527527
break EXPR_PREFIX
528528
}
529529

Sources/SwiftParser/Types.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,9 @@ extension Parser.Lookahead {
694694
switch self.currentToken {
695695
case TokenSpec(.Any):
696696
self.consumeAnyToken()
697+
case TokenSpec(.prefixOperator) where self.currentToken.tokenText == "~":
698+
self.consumeAnyToken();
699+
fallthrough
697700
case TokenSpec(.Self), TokenSpec(.identifier):
698701
guard self.canParseTypeIdentifier() else {
699702
return false

Tests/SwiftParserTest/TypeTests.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,40 @@ final class TypeTests: ParserTestCase {
309309
)
310310
}
311311

312+
func testInverseTypes() {
313+
assertParse(
314+
"[~Copyable]()"
315+
)
316+
317+
assertParse(
318+
"[any ~Copyable]()"
319+
)
320+
321+
assertParse(
322+
"[any P & ~Copyable]()"
323+
)
324+
325+
assertParse(
326+
"[P & ~Copyable]()"
327+
)
328+
329+
assertParse(
330+
"X<~Copyable>()"
331+
)
332+
333+
assertParse(
334+
"X<any ~Copyable>()"
335+
)
336+
337+
assertParse(
338+
"X<P & ~Copyable>()"
339+
)
340+
341+
assertParse(
342+
"X<any P & ~Copyable>()"
343+
)
344+
}
345+
312346
func testTypedThrows() {
313347
assertParse(
314348
"""

0 commit comments

Comments
 (0)