Skip to content

Commit 7a8c1ef

Browse files
authored
Merge pull request #2585 from DougGregor/parse-suppressed-constraints-and-ownership-params-6.0
[6.0] Fix parsing issues related to suppressed conformances / noncopyable generics
2 parents d12e37f + 752c087 commit 7a8c1ef

File tree

4 files changed

+110
-1
lines changed

4 files changed

+110
-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/TokenConsumer.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ extension TokenConsumer {
374374
return false
375375
}
376376

377+
case .prefixOperator where lexeme.isContextualPunctuator("~"):
378+
return true
379+
377380
default:
378381
return false
379382
}

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: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,109 @@ 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+
346+
func testInverseTypesAsExpr() {
347+
assertParse(
348+
"(~Copyable).self"
349+
)
350+
351+
assertParse(
352+
"~Copyable.self"
353+
)
354+
355+
assertParse(
356+
"(any ~Copyable).self"
357+
)
358+
}
359+
360+
func testInverseTypesInParameter() {
361+
assertParse(
362+
"func f(_: borrowing ~Copyable) {}"
363+
)
364+
365+
assertParse(
366+
"func f(_: consuming ~Copyable) {}"
367+
)
368+
369+
assertParse(
370+
"func f(_: borrowing any ~Copyable) {}"
371+
)
372+
373+
assertParse(
374+
"func f(_: consuming any ~Copyable) {}"
375+
)
376+
377+
assertParse(
378+
"func f(_: ~Copyable) {}"
379+
)
380+
381+
assertParse(
382+
"typealias T = (~Copyable) -> Void"
383+
)
384+
385+
assertParse(
386+
"typealias T = (_ x: ~Copyable) -> Void"
387+
)
388+
389+
assertParse(
390+
"typealias T = (borrowing ~Copyable) -> Void"
391+
)
392+
393+
assertParse(
394+
"typealias T = (_ x: borrowing ~Copyable) -> Void"
395+
)
396+
397+
assertParse(
398+
"typealias T = (borrowing any ~Copyable) -> Void"
399+
)
400+
401+
assertParse(
402+
"typealias T = (_ x: borrowing any ~Copyable) -> Void"
403+
)
404+
405+
assertParse(
406+
"func f(_: any borrowing 1️⃣~Copyable) {}",
407+
diagnostics: [
408+
DiagnosticSpec(
409+
message: "unexpected code '~Copyable' in parameter clause"
410+
)
411+
]
412+
)
413+
}
414+
312415
func testTypedThrows() {
313416
assertParse(
314417
"""

0 commit comments

Comments
 (0)