Skip to content

Fix crash when a switch case's last statement is formatter-ignored#1222

Open
nenadvulic wants to merge 1 commit into
swiftlang:mainfrom
nenadvulic:fix-309-ignore-in-switch-case
Open

Fix crash when a switch case's last statement is formatter-ignored#1222
nenadvulic wants to merge 1 commit into
swiftlang:mainfrom
nenadvulic:fix-309-ignore-in-switch-case

Conversation

@nenadvulic

Copy link
Copy Markdown

Summary

Fixes #309.

Linting or formatting a file with // swift-format-ignore on the last statement of a switch case crashes:

switch val {
case .foo:
  // swift-format-ignore
  print("Foo")
case .bar:
  print("Bar")
}
SwiftFormat/PrettyPrint.swift: Assertion failed: Too many unresolved delimiter token lengths.

Root cause

visit(SwitchCaseSyntax) emits an .open group after the case label and attaches the matching .close as an after token on the case's last token. When the last statement is formatter-ignored it is emitted verbatim and its tokens are never visited (the node is skipped), so the after close tokens are dropped and the group is never closed.

This is the same hazard that visit(CodeBlockItemListSyntax) already documents and avoids ("the tokens after item.lastToken would be ignored and leave unclosed open tokens").

Fix

When the case's last statement is formatter-ignored, attach the closing tokens before the next token (the next case or the closing brace) instead of after the case's last token — mirroring the existing handling for empty cases.

Tests

Added testIgnoreStatementInSwitchCase and testIgnoreLastStatementInSwitchCase to IgnoreNodeTests. Both crash without the fix and pass with it. Full test suite passes (934 tests, 0 failures).

The SwitchCaseSyntax visitor emits an open group after the case label and
attaches the matching close as an 'after' token on the case's last token.
When the last statement is formatter-ignored it is emitted verbatim and its
tokens are never visited, so the close was dropped, leaving the group open
and tripping the 'Too many unresolved delimiter token lengths' assertion in
PrettyPrint. Attach the closing tokens before the next token in that case,
mirroring the empty-case handling.

Fixes swiftlang#309.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SR-14529] swift-format-ignore inside switch causes linter to crash

1 participant