Skip to content

Commit 5c91359

Browse files
committed
Fix invalid rewrite in UseExplicitNilCheckInConditions by skipping when explicit optional type annotation is present
1 parent 80bcc35 commit 5c91359

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

Documentation/RuleDocumentation.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,10 @@ than binding and immediately discarding the value.
490490
For example, `if let _ = someValue { ... }` is forbidden. Use `if someValue != nil { ... }`
491491
instead.
492492

493+
Note: If the conditional binding carries an explicit type annotation (e.g. `if let _: S? = expr`
494+
or `if let _: S = expr`), we skip the transformation. Such annotations can be necessary to
495+
drive generic type inference when a function mentions a type only in its return position.
496+
493497
Lint: `let _ = expr` inside a condition list will yield a lint error.
494498

495499
Format: `let _ = expr` inside a condition list will be replaced by `expr != nil`.

Sources/SwiftFormat/Rules/UseExplicitNilCheckInConditions.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import SwiftSyntaxBuilder
1919
/// For example, `if let _ = someValue { ... }` is forbidden. Use `if someValue != nil { ... }`
2020
/// instead.
2121
///
22+
/// Note: If the conditional binding carries an explicit type annotation (e.g. `if let _: S? = expr`
23+
/// or `if let _: S = expr`), we skip the transformation. Such annotations can be necessary to
24+
/// drive generic type inference when a function mentions a type only in its return position.
25+
///
2226
/// Lint: `let _ = expr` inside a condition list will yield a lint error.
2327
///
2428
/// Format: `let _ = expr` inside a condition list will be replaced by `expr != nil`.
@@ -29,7 +33,8 @@ public final class UseExplicitNilCheckInConditions: SyntaxFormatRule {
2933
case .optionalBinding(let optionalBindingCondition):
3034
guard
3135
let initializerClause = optionalBindingCondition.initializer,
32-
isDiscardedAssignmentPattern(optionalBindingCondition.pattern)
36+
isDiscardedAssignmentPattern(optionalBindingCondition.pattern),
37+
optionalBindingCondition.typeAnnotation == nil
3338
else {
3439
return node
3540
}

Tests/SwiftFormatTests/Rules/UseExplicitNilCheckInConditionsTests.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,18 @@ final class UseExplicitNilCheckInConditionsTests: LintOrFormatRuleTestCase {
160160
]
161161
)
162162
}
163+
164+
func testTypeAnnotations() {
165+
assertFormatting(
166+
UseExplicitNilCheckInConditions.self,
167+
input: """
168+
if let _: F = foo() {}
169+
if let _: S? = foo() {}
170+
""",
171+
expected: """
172+
if let _: F = foo() {}
173+
if let _: S? = foo() {}
174+
"""
175+
)
176+
}
163177
}

0 commit comments

Comments
 (0)