File tree Expand file tree Collapse file tree 2 files changed +32
-1
lines changed
Sources/SwiftFormat/Rules
Tests/SwiftFormatTests/Rules Expand file tree Collapse file tree 2 files changed +32
-1
lines changed Original file line number Diff line number Diff line change @@ -29,7 +29,8 @@ public final class UseExplicitNilCheckInConditions: SyntaxFormatRule {
2929 case . optionalBinding( let optionalBindingCondition) :
3030 guard
3131 let initializerClause = optionalBindingCondition. initializer,
32- isDiscardedAssignmentPattern ( optionalBindingCondition. pattern)
32+ isDiscardedAssignmentPattern ( optionalBindingCondition. pattern) ,
33+ !hasOptionalTypeAnnotation( optionalBindingCondition)
3334 else {
3435 return node
3536 }
@@ -71,6 +72,19 @@ public final class UseExplicitNilCheckInConditions: SyntaxFormatRule {
7172 return exprPattern. expression. is ( DiscardAssignmentExprSyntax . self)
7273 }
7374
75+ /// Returns true if the conditional binding carries an explicit optional type annotation,
76+ /// e.g. `if let _: S? = expr { ... }`.
77+ ///
78+ /// We skip rewriting in this case. While we could preserve the coercion by rewriting
79+ /// to `(expr as S?) != nil`, skipping is safer—it avoids potential changes in operator
80+ /// precedence and keeps the original semantics intact.
81+ private func hasOptionalTypeAnnotation( _ bindingCondition: OptionalBindingConditionSyntax ) -> Bool {
82+ guard let typeAnnotation = bindingCondition. typeAnnotation else {
83+ return false
84+ }
85+ return typeAnnotation. type. is ( OptionalTypeSyntax . self)
86+ }
87+
7488 /// Adds parentheses around the given expression if necessary to ensure that it will be parsed
7589 /// correctly when followed by `!= nil`.
7690 ///
Original file line number Diff line number Diff line change @@ -160,4 +160,21 @@ final class UseExplicitNilCheckInConditionsTests: LintOrFormatRuleTestCase {
160160 ]
161161 )
162162 }
163+
164+ func testTypeAnnotations( ) {
165+ assertFormatting (
166+ UseExplicitNilCheckInConditions . self,
167+ input: """
168+ if 1️⃣let _: F = foo() {}
169+ if let _: S? = foo() {}
170+ """ ,
171+ expected: """
172+ if foo() != nil {}
173+ if let _: S? = foo() {}
174+ """ ,
175+ findings: [
176+ FindingSpec ( " 1️⃣ " , message: " compare this value using `!= nil` instead of binding and discarding it " )
177+ ]
178+ )
179+ }
163180}
You can’t perform that action at this time.
0 commit comments