diff --git a/Sources/Rules.swift b/Sources/Rules.swift index 2d8cdba4..8df4472b 100644 --- a/Sources/Rules.swift +++ b/Sources/Rules.swift @@ -3180,6 +3180,15 @@ public struct _FormatRules { return } + // Make sure we aren't in a failable `init?`, where explicit return is required + if let lastSignificantKeywordIndex = formatter.indexOfLastSignificantKeyword(at: startOfScopeIndex), + formatter.tokens[lastSignificantKeywordIndex] == .keyword("init"), + let nextToken = formatter.next(.nonSpaceOrCommentOrLinebreak, after: lastSignificantKeywordIndex), + nextToken == .operator("?", .postfix) + { + return + } + // Removes return statements in the given single-statement scope func removeReturn(atStartOfScope startOfScopeIndex: Int) { // If this scope is a single-statement if or switch statement then we have to recursively diff --git a/Tests/RulesTests+Redundancy.swift b/Tests/RulesTests+Redundancy.swift index 8209313c..7f894834 100644 --- a/Tests/RulesTests+Redundancy.swift +++ b/Tests/RulesTests+Redundancy.swift @@ -2220,6 +2220,39 @@ class RedundancyTests: RulesTests { testFormatting(for: input, rule: FormatRules.redundantReturn) } + func testNoRemoveReturnInFailableInitWithConditional() { + let input = """ + init?(optionalHex: String?) { + if let optionalHex { + self.init(hex: optionalHex) + } else { + return nil + } + } + """ + let options = FormatOptions(swiftVersion: "5.9") + testFormatting(for: input, rule: FormatRules.redundantReturn, options: options) + } + + func testNoRemoveReturnInFailableInitWithNestedConditional() { + let input = """ + init?(optionalHex: String?) { + if let optionalHex { + self.init(hex: optionalHex) + } else { + switch foo { + case .foo: + self.init() + case .bar: + return nil + } + } + } + """ + let options = FormatOptions(swiftVersion: "5.9") + testFormatting(for: input, rule: FormatRules.redundantReturn, options: options) + } + func testRemoveReturnInFailableInit() { let input = "init?() { return nil }" let output = "init?() { nil }"