From c9183947179011ac07d8a70960340c2e1e3ca313 Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Sat, 14 May 2022 19:49:09 +0100 Subject: [PATCH] Fix unusedArguments shadowing bug --- Snapshots/Issues/1183.swift | 21 +++++++++++++++++++++ Snapshots/Issues/1184.swift | 4 ++++ Sources/Rules.swift | 24 +++++++++++++++++++----- Tests/RulesTests+Redundancy.swift | 12 ++++++++++++ 4 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 Snapshots/Issues/1183.swift create mode 100644 Snapshots/Issues/1184.swift diff --git a/Snapshots/Issues/1183.swift b/Snapshots/Issues/1183.swift new file mode 100644 index 000000000..7b97141b0 --- /dev/null +++ b/Snapshots/Issues/1183.swift @@ -0,0 +1,21 @@ +func typeMismatch( + for symbol: String, + index: Int, + expected types: [String], + got: String +) -> RuntimeErrorType { + var types = Set(types).sorted() + if let index = types.firstIndex(of: "block") { + types.append(types.remove(at: index)) + } + let expected: String + switch types.count { + case 1: + expected = types[0] + case 2: + expected = "\(types[0]) or \(types[1])" + default: + expected = "\(types.dropLast().joined(separator: ", ")), or \(types.last!)" + } + return .typeMismatch(for: symbol, index: index, expected: expected, got: got) +} diff --git a/Snapshots/Issues/1184.swift b/Snapshots/Issues/1184.swift new file mode 100644 index 000000000..d9d618858 --- /dev/null +++ b/Snapshots/Issues/1184.swift @@ -0,0 +1,4 @@ +func foo(index: Int) { + for index in 0 ..< 1 {} + print(index) +} diff --git a/Sources/Rules.swift b/Sources/Rules.swift index 5dacaa031..084a5bdb0 100644 --- a/Sources/Rules.swift +++ b/Sources/Rules.swift @@ -3675,6 +3675,7 @@ public struct _FormatRules { var isDeclaration = false var wasDeclaration = false var isConditional = false + var isGuard = false var locals = locals var tempLocals = Set() func pushLocals() { @@ -3701,6 +3702,8 @@ public struct _FormatRules { } let token = formatter.tokens[i] switch token { + case .keyword("guard"): + isGuard = true case .keyword("let"), .keyword("var"), .keyword("func"), .keyword("for"): isDeclaration = true var i = i @@ -3728,15 +3731,26 @@ public struct _FormatRules { } } case .startOfScope("{"): - if !formatter.isStartOfClosure(at: i) { - pushLocals() - } guard let endIndex = formatter.endOfScope(at: i) else { argNames.removeAll() return } - removeUsed(from: &argNames, with: &associatedData, - locals: locals, in: i + 1 ..< endIndex) + if formatter.isStartOfClosure(at: i) { + removeUsed(from: &argNames, with: &associatedData, + locals: locals, in: i + 1 ..< endIndex) + } else if isGuard { + removeUsed(from: &argNames, with: &associatedData, + locals: locals, in: i + 1 ..< endIndex) + pushLocals() + } else { + let prevLocals = locals + pushLocals() + removeUsed(from: &argNames, with: &associatedData, + locals: locals, in: i + 1 ..< endIndex) + locals = prevLocals + } + + isGuard = false i = endIndex case .endOfScope("case"), .endOfScope("default"): pushLocals() diff --git a/Tests/RulesTests+Redundancy.swift b/Tests/RulesTests+Redundancy.swift index f62158bae..01ff3159d 100644 --- a/Tests/RulesTests+Redundancy.swift +++ b/Tests/RulesTests+Redundancy.swift @@ -5161,6 +5161,18 @@ class RedundancyTests: RulesTests { testFormatting(for: input, rule: FormatRules.unusedArguments) } + func testShadowedUsedArguments4() { + let input = """ + func foo(bar: Int) { + if let bar = baz { + return + } + print(bar) + } + """ + testFormatting(for: input, rule: FormatRules.unusedArguments) + } + func testTryArgumentNotMarkedUnused() { let input = """ func foo(bar: String) throws -> String? {