diff --git a/Sources/FormattingHelpers.swift b/Sources/FormattingHelpers.swift index f6fe6761..206fadd8 100644 --- a/Sources/FormattingHelpers.swift +++ b/Sources/FormattingHelpers.swift @@ -943,15 +943,14 @@ extension Formatter { } // Common implementation for the `hoistTry` and `hoistAwait` rules - func hoistEffectKeyword(at i: Int, isEffectAbsorbingFunction: (Token) -> Bool) { - guard case let .keyword(keyword)? = token(at: i), - ["try", "await"].contains(keyword) - else { - assertionFailure() - return - } - - guard let scopeStart = index(of: .startOfScope("("), before: i), + // Hoists the first keyword of the specified type out of the specified scope + func hoistEffectKeyword( + _ keyword: String, + inScopeAt scopeStart: Int, + isEffectCapturing: (Token) -> Bool + ) { + assert(["try", "await"].contains(keyword)) + guard let i = index(of: .keyword(keyword), after: scopeStart), token(at: i + 1)?.isUnwrapOperator == false else { return @@ -989,7 +988,7 @@ extension Formatter { let token = tokens[i] switch token { case .identifier where prevToken == .startOfScope("("): - if isEffectAbsorbingFunction(token) { + if isEffectCapturing(token) { return } case let .keyword(name) where ["is", "as", "try", "await"].contains(name): diff --git a/Sources/Rules.swift b/Sources/Rules.swift index 0ffd9c72..402edd01 100644 --- a/Sources/Rules.swift +++ b/Sources/Rules.swift @@ -4277,8 +4277,8 @@ public struct _FormatRules { help: "Move inline `try` keyword(s) to start of expression.", options: ["throwcapturing"] ) { formatter in - formatter.forEach(.keyword("try")) { i, _ in - formatter.hoistEffectKeyword(at: i) { token in + formatter.forEach(.startOfScope("(")) { i, _ in + formatter.hoistEffectKeyword("try", inScopeAt: i) { token in guard case let .identifier(name) = token else { return false } @@ -4295,8 +4295,8 @@ public struct _FormatRules { ) { formatter in guard formatter.options.swiftVersion >= "5.5" else { return } - formatter.forEach(.keyword("await")) { i, _ in - formatter.hoistEffectKeyword(at: i) { token in + formatter.forEach(.startOfScope("(")) { i, _ in + formatter.hoistEffectKeyword("await", inScopeAt: i) { token in formatter.options.asyncCapturing.contains(token.string) } }