Skip to content

Commit 5e42f4c

Browse files
authored
Merge pull request #2971 from DougGregor/unsafe-for-in-loop
[SE-0458] Implement "unsafe" effect for the for-in loop
2 parents 3688938 + 7271424 commit 5e42f4c

File tree

10 files changed

+170
-78
lines changed

10 files changed

+170
-78
lines changed

CodeGeneration/Sources/SyntaxSupport/StmtNodes.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,12 @@ public let STMT_NODES: [Node] = [
284284
kind: .token(choices: [.keyword(.await)]),
285285
isOptional: true
286286
),
287+
Child(
288+
name: "unsafeKeyword",
289+
kind: .token(choices: [.keyword(.unsafe)]),
290+
experimentalFeature: .unsafeExpression,
291+
isOptional: true
292+
),
287293
Child(
288294
name: "caseKeyword",
289295
kind: .token(choices: [.keyword(.case)]),

Sources/SwiftParser/Statements.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,16 @@ extension Parser {
570570
let tryKeyword = self.consume(if: .keyword(.try))
571571
let awaitKeyword = self.consume(if: .keyword(.await))
572572

573+
let unsafeKeyword: RawTokenSyntax?
574+
if let modifierKeyword = ExpressionModifierKeyword(
575+
lexeme: self.currentToken,
576+
experimentalFeatures: self.experimentalFeatures
577+
), modifierKeyword == .unsafe, !self.peek(isAt: .keyword(.in)) {
578+
unsafeKeyword = self.consumeAnyToken(remapping: .keyword)
579+
} else {
580+
unsafeKeyword = nil
581+
}
582+
573583
// Parse the pattern. This is either 'case <refutable pattern>' or just a
574584
// normal pattern.
575585
let caseKeyword = self.consume(if: .keyword(.case))
@@ -624,6 +634,7 @@ extension Parser {
624634
forKeyword: forKeyword,
625635
tryKeyword: tryKeyword,
626636
awaitKeyword: awaitKeyword,
637+
unsafeKeyword: unsafeKeyword,
627638
caseKeyword: caseKeyword,
628639
pattern: pattern,
629640
typeAnnotation: type,

Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,8 +1373,12 @@ public func childName(_ keyPath: AnyKeyPath) -> String? {
13731373
return "unexpectedBetweenTryKeywordAndAwaitKeyword"
13741374
case \ForStmtSyntax.awaitKeyword:
13751375
return "awaitKeyword"
1376-
case \ForStmtSyntax.unexpectedBetweenAwaitKeywordAndCaseKeyword:
1377-
return "unexpectedBetweenAwaitKeywordAndCaseKeyword"
1376+
case \ForStmtSyntax.unexpectedBetweenAwaitKeywordAndUnsafeKeyword:
1377+
return "unexpectedBetweenAwaitKeywordAndUnsafeKeyword"
1378+
case \ForStmtSyntax.unsafeKeyword:
1379+
return "unsafeKeyword"
1380+
case \ForStmtSyntax.unexpectedBetweenUnsafeKeywordAndCaseKeyword:
1381+
return "unexpectedBetweenUnsafeKeywordAndCaseKeyword"
13781382
case \ForStmtSyntax.caseKeyword:
13791383
return "caseKeyword"
13801384
case \ForStmtSyntax.unexpectedBetweenCaseKeywordAndPattern:

Sources/SwiftSyntax/generated/RenamedChildrenCompatibility.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2818,7 +2818,7 @@ extension ForStmtSyntax {
28182818
}
28192819
}
28202820

2821-
@available(*, deprecated, renamed: "init(leadingTrivia:_:forKeyword:_:tryKeyword:_:awaitKeyword:_:caseKeyword:_:pattern:_:typeAnnotation:_:inKeyword:_:sequence:_:whereClause:_:body:_:trailingTrivia:)")
2821+
@available(*, deprecated, renamed: "init(leadingTrivia:_:forKeyword:_:tryKeyword:_:awaitKeyword:_:unsafeKeyword:_:caseKeyword:_:pattern:_:typeAnnotation:_:inKeyword:_:sequence:_:whereClause:_:body:_:trailingTrivia:)")
28222822
@_disfavoredOverload
28232823
public init(
28242824
leadingTrivia: Trivia? = nil,
@@ -2828,7 +2828,9 @@ extension ForStmtSyntax {
28282828
tryKeyword: TokenSyntax? = nil,
28292829
_ unexpectedBetweenTryKeywordAndAwaitKeyword: UnexpectedNodesSyntax? = nil,
28302830
awaitKeyword: TokenSyntax? = nil,
2831-
_ unexpectedBetweenAwaitKeywordAndCaseKeyword: UnexpectedNodesSyntax? = nil,
2831+
_ unexpectedBetweenAwaitKeywordAndUnsafeKeyword: UnexpectedNodesSyntax? = nil,
2832+
unsafeKeyword: TokenSyntax? = nil,
2833+
_ unexpectedBetweenUnsafeKeywordAndCaseKeyword: UnexpectedNodesSyntax? = nil,
28322834
caseKeyword: TokenSyntax? = nil,
28332835
_ unexpectedBetweenCaseKeywordAndPattern: UnexpectedNodesSyntax? = nil,
28342836
pattern: some PatternSyntaxProtocol,
@@ -2853,7 +2855,9 @@ extension ForStmtSyntax {
28532855
tryKeyword: tryKeyword,
28542856
unexpectedBetweenTryKeywordAndAwaitKeyword,
28552857
awaitKeyword: awaitKeyword,
2856-
unexpectedBetweenAwaitKeywordAndCaseKeyword,
2858+
unexpectedBetweenAwaitKeywordAndUnsafeKeyword,
2859+
unsafeKeyword: unsafeKeyword,
2860+
unexpectedBetweenUnsafeKeywordAndCaseKeyword,
28572861
caseKeyword: caseKeyword,
28582862
unexpectedBetweenCaseKeywordAndPattern,
28592863
pattern: pattern,

Sources/SwiftSyntax/generated/raw/RawSyntaxNodesEF.swift

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,7 +1522,9 @@ public struct RawForStmtSyntax: RawStmtSyntaxNodeProtocol {
15221522
tryKeyword: RawTokenSyntax?,
15231523
_ unexpectedBetweenTryKeywordAndAwaitKeyword: RawUnexpectedNodesSyntax? = nil,
15241524
awaitKeyword: RawTokenSyntax?,
1525-
_ unexpectedBetweenAwaitKeywordAndCaseKeyword: RawUnexpectedNodesSyntax? = nil,
1525+
_ unexpectedBetweenAwaitKeywordAndUnsafeKeyword: RawUnexpectedNodesSyntax? = nil,
1526+
unsafeKeyword: RawTokenSyntax?,
1527+
_ unexpectedBetweenUnsafeKeywordAndCaseKeyword: RawUnexpectedNodesSyntax? = nil,
15261528
caseKeyword: RawTokenSyntax?,
15271529
_ unexpectedBetweenCaseKeywordAndPattern: RawUnexpectedNodesSyntax? = nil,
15281530
pattern: some RawPatternSyntaxNodeProtocol,
@@ -1540,29 +1542,31 @@ public struct RawForStmtSyntax: RawStmtSyntaxNodeProtocol {
15401542
arena: __shared RawSyntaxArena
15411543
) {
15421544
let raw = RawSyntax.makeLayout(
1543-
kind: .forStmt, uninitializedCount: 21, arena: arena) { layout in
1545+
kind: .forStmt, uninitializedCount: 23, arena: arena) { layout in
15441546
layout.initialize(repeating: nil)
15451547
layout[0] = unexpectedBeforeForKeyword?.raw
15461548
layout[1] = forKeyword.raw
15471549
layout[2] = unexpectedBetweenForKeywordAndTryKeyword?.raw
15481550
layout[3] = tryKeyword?.raw
15491551
layout[4] = unexpectedBetweenTryKeywordAndAwaitKeyword?.raw
15501552
layout[5] = awaitKeyword?.raw
1551-
layout[6] = unexpectedBetweenAwaitKeywordAndCaseKeyword?.raw
1552-
layout[7] = caseKeyword?.raw
1553-
layout[8] = unexpectedBetweenCaseKeywordAndPattern?.raw
1554-
layout[9] = pattern.raw
1555-
layout[10] = unexpectedBetweenPatternAndTypeAnnotation?.raw
1556-
layout[11] = typeAnnotation?.raw
1557-
layout[12] = unexpectedBetweenTypeAnnotationAndInKeyword?.raw
1558-
layout[13] = inKeyword.raw
1559-
layout[14] = unexpectedBetweenInKeywordAndSequence?.raw
1560-
layout[15] = sequence.raw
1561-
layout[16] = unexpectedBetweenSequenceAndWhereClause?.raw
1562-
layout[17] = whereClause?.raw
1563-
layout[18] = unexpectedBetweenWhereClauseAndBody?.raw
1564-
layout[19] = body.raw
1565-
layout[20] = unexpectedAfterBody?.raw
1553+
layout[6] = unexpectedBetweenAwaitKeywordAndUnsafeKeyword?.raw
1554+
layout[7] = unsafeKeyword?.raw
1555+
layout[8] = unexpectedBetweenUnsafeKeywordAndCaseKeyword?.raw
1556+
layout[9] = caseKeyword?.raw
1557+
layout[10] = unexpectedBetweenCaseKeywordAndPattern?.raw
1558+
layout[11] = pattern.raw
1559+
layout[12] = unexpectedBetweenPatternAndTypeAnnotation?.raw
1560+
layout[13] = typeAnnotation?.raw
1561+
layout[14] = unexpectedBetweenTypeAnnotationAndInKeyword?.raw
1562+
layout[15] = inKeyword.raw
1563+
layout[16] = unexpectedBetweenInKeywordAndSequence?.raw
1564+
layout[17] = sequence.raw
1565+
layout[18] = unexpectedBetweenSequenceAndWhereClause?.raw
1566+
layout[19] = whereClause?.raw
1567+
layout[20] = unexpectedBetweenWhereClauseAndBody?.raw
1568+
layout[21] = body.raw
1569+
layout[22] = unexpectedAfterBody?.raw
15661570
}
15671571
self.init(unchecked: raw)
15681572
}
@@ -1591,64 +1595,72 @@ public struct RawForStmtSyntax: RawStmtSyntaxNodeProtocol {
15911595
layoutView.children[5].map(RawTokenSyntax.init(raw:))
15921596
}
15931597

1594-
public var unexpectedBetweenAwaitKeywordAndCaseKeyword: RawUnexpectedNodesSyntax? {
1598+
public var unexpectedBetweenAwaitKeywordAndUnsafeKeyword: RawUnexpectedNodesSyntax? {
15951599
layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:))
15961600
}
15971601

1598-
public var caseKeyword: RawTokenSyntax? {
1602+
public var unsafeKeyword: RawTokenSyntax? {
15991603
layoutView.children[7].map(RawTokenSyntax.init(raw:))
16001604
}
16011605

1602-
public var unexpectedBetweenCaseKeywordAndPattern: RawUnexpectedNodesSyntax? {
1606+
public var unexpectedBetweenUnsafeKeywordAndCaseKeyword: RawUnexpectedNodesSyntax? {
16031607
layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:))
16041608
}
16051609

1610+
public var caseKeyword: RawTokenSyntax? {
1611+
layoutView.children[9].map(RawTokenSyntax.init(raw:))
1612+
}
1613+
1614+
public var unexpectedBetweenCaseKeywordAndPattern: RawUnexpectedNodesSyntax? {
1615+
layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:))
1616+
}
1617+
16061618
public var pattern: RawPatternSyntax {
1607-
layoutView.children[9].map(RawPatternSyntax.init(raw:))!
1619+
layoutView.children[11].map(RawPatternSyntax.init(raw:))!
16081620
}
16091621

16101622
public var unexpectedBetweenPatternAndTypeAnnotation: RawUnexpectedNodesSyntax? {
1611-
layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:))
1623+
layoutView.children[12].map(RawUnexpectedNodesSyntax.init(raw:))
16121624
}
16131625

16141626
public var typeAnnotation: RawTypeAnnotationSyntax? {
1615-
layoutView.children[11].map(RawTypeAnnotationSyntax.init(raw:))
1627+
layoutView.children[13].map(RawTypeAnnotationSyntax.init(raw:))
16161628
}
16171629

16181630
public var unexpectedBetweenTypeAnnotationAndInKeyword: RawUnexpectedNodesSyntax? {
1619-
layoutView.children[12].map(RawUnexpectedNodesSyntax.init(raw:))
1631+
layoutView.children[14].map(RawUnexpectedNodesSyntax.init(raw:))
16201632
}
16211633

16221634
public var inKeyword: RawTokenSyntax {
1623-
layoutView.children[13].map(RawTokenSyntax.init(raw:))!
1635+
layoutView.children[15].map(RawTokenSyntax.init(raw:))!
16241636
}
16251637

16261638
public var unexpectedBetweenInKeywordAndSequence: RawUnexpectedNodesSyntax? {
1627-
layoutView.children[14].map(RawUnexpectedNodesSyntax.init(raw:))
1639+
layoutView.children[16].map(RawUnexpectedNodesSyntax.init(raw:))
16281640
}
16291641

16301642
public var sequence: RawExprSyntax {
1631-
layoutView.children[15].map(RawExprSyntax.init(raw:))!
1643+
layoutView.children[17].map(RawExprSyntax.init(raw:))!
16321644
}
16331645

16341646
public var unexpectedBetweenSequenceAndWhereClause: RawUnexpectedNodesSyntax? {
1635-
layoutView.children[16].map(RawUnexpectedNodesSyntax.init(raw:))
1647+
layoutView.children[18].map(RawUnexpectedNodesSyntax.init(raw:))
16361648
}
16371649

16381650
public var whereClause: RawWhereClauseSyntax? {
1639-
layoutView.children[17].map(RawWhereClauseSyntax.init(raw:))
1651+
layoutView.children[19].map(RawWhereClauseSyntax.init(raw:))
16401652
}
16411653

16421654
public var unexpectedBetweenWhereClauseAndBody: RawUnexpectedNodesSyntax? {
1643-
layoutView.children[18].map(RawUnexpectedNodesSyntax.init(raw:))
1655+
layoutView.children[20].map(RawUnexpectedNodesSyntax.init(raw:))
16441656
}
16451657

16461658
public var body: RawCodeBlockSyntax {
1647-
layoutView.children[19].map(RawCodeBlockSyntax.init(raw:))!
1659+
layoutView.children[21].map(RawCodeBlockSyntax.init(raw:))!
16481660
}
16491661

16501662
public var unexpectedAfterBody: RawUnexpectedNodesSyntax? {
1651-
layoutView.children[20].map(RawUnexpectedNodesSyntax.init(raw:))
1663+
layoutView.children[22].map(RawUnexpectedNodesSyntax.init(raw:))
16521664
}
16531665
}
16541666

Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,28 +1341,30 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
13411341
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
13421342
}
13431343
func validateForStmtSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) {
1344-
assert(layout.count == 21)
1344+
assert(layout.count == 23)
13451345
assertNoError(kind, 0, verify(layout[0], as: RawUnexpectedNodesSyntax?.self))
13461346
assertNoError(kind, 1, verify(layout[1], as: RawTokenSyntax.self, tokenChoices: [.keyword("for")]))
13471347
assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self))
13481348
assertNoError(kind, 3, verify(layout[3], as: RawTokenSyntax?.self, tokenChoices: [.keyword("try")]))
13491349
assertNoError(kind, 4, verify(layout[4], as: RawUnexpectedNodesSyntax?.self))
13501350
assertNoError(kind, 5, verify(layout[5], as: RawTokenSyntax?.self, tokenChoices: [.keyword("await")]))
13511351
assertNoError(kind, 6, verify(layout[6], as: RawUnexpectedNodesSyntax?.self))
1352-
assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax?.self, tokenChoices: [.keyword("case")]))
1352+
assertNoError(kind, 7, verify(layout[7], as: RawTokenSyntax?.self, tokenChoices: [.keyword("unsafe")]))
13531353
assertNoError(kind, 8, verify(layout[8], as: RawUnexpectedNodesSyntax?.self))
1354-
assertNoError(kind, 9, verify(layout[9], as: RawPatternSyntax.self))
1354+
assertNoError(kind, 9, verify(layout[9], as: RawTokenSyntax?.self, tokenChoices: [.keyword("case")]))
13551355
assertNoError(kind, 10, verify(layout[10], as: RawUnexpectedNodesSyntax?.self))
1356-
assertNoError(kind, 11, verify(layout[11], as: RawTypeAnnotationSyntax?.self))
1356+
assertNoError(kind, 11, verify(layout[11], as: RawPatternSyntax.self))
13571357
assertNoError(kind, 12, verify(layout[12], as: RawUnexpectedNodesSyntax?.self))
1358-
assertNoError(kind, 13, verify(layout[13], as: RawTokenSyntax.self, tokenChoices: [.keyword("in")]))
1358+
assertNoError(kind, 13, verify(layout[13], as: RawTypeAnnotationSyntax?.self))
13591359
assertNoError(kind, 14, verify(layout[14], as: RawUnexpectedNodesSyntax?.self))
1360-
assertNoError(kind, 15, verify(layout[15], as: RawExprSyntax.self))
1360+
assertNoError(kind, 15, verify(layout[15], as: RawTokenSyntax.self, tokenChoices: [.keyword("in")]))
13611361
assertNoError(kind, 16, verify(layout[16], as: RawUnexpectedNodesSyntax?.self))
1362-
assertNoError(kind, 17, verify(layout[17], as: RawWhereClauseSyntax?.self))
1362+
assertNoError(kind, 17, verify(layout[17], as: RawExprSyntax.self))
13631363
assertNoError(kind, 18, verify(layout[18], as: RawUnexpectedNodesSyntax?.self))
1364-
assertNoError(kind, 19, verify(layout[19], as: RawCodeBlockSyntax.self))
1364+
assertNoError(kind, 19, verify(layout[19], as: RawWhereClauseSyntax?.self))
13651365
assertNoError(kind, 20, verify(layout[20], as: RawUnexpectedNodesSyntax?.self))
1366+
assertNoError(kind, 21, verify(layout[21], as: RawCodeBlockSyntax.self))
1367+
assertNoError(kind, 22, verify(layout[22], as: RawUnexpectedNodesSyntax?.self))
13661368
}
13671369
func validateForceUnwrapExprSyntax(kind: SyntaxKind, layout: RawSyntaxBuffer) {
13681370
assert(layout.count == 5)

0 commit comments

Comments
 (0)