SwiftLint icon indicating copy to clipboard operation
SwiftLint copied to clipboard

`redundant_discardable_let` rule causes a compilation error for things that are wrapped in a result-builder annotation

Open jeremypearson opened this issue 3 years ago • 5 comments

New Issue Checklist

Describe the bug

redundant_discardable_let rule causes a compilation error for things that are wrapped in a result-builder annotation.

Here's a link to the rule on GitHub which contains the bug: https://github.com/realm/SwiftLint/blob/master/Source/SwiftLintFramework/Rules/Style/RedundantDiscardableLetRule.swift

It's unsafe, for say, the body property of a struct which conforms to the View protocol from SwiftUI (and which therefore has a body property that's implicitly-annotated with the @ViewBuilder result-builder annotation), to replace this code snippet:

// Inside struct conforming to `View` protocol from `SwiftUI`.
var body: some View {
    let _ = 10

    Text("Hello, world!")
        .padding()
}

with this code snippet:

// Inside struct conforming to `View` protocol from `SwiftUI`.
var body: some View {
    _ = 10

    Text("Hello, world!")
        .padding()
}

as making such a replacement, would result in a compilation error. In this specific example, that compilation error will be: "Type '()' cannot conform to 'View'".

Complete output when running SwiftLint, including the stack trace and command used
$ swiftlint lint /Users/jeremy/dev/xcode/SwiftLintBugDemoApp/SwiftLintBugDemoApp/ContentView.swift
Linting Swift files at paths /Users/jeremy/dev/xcode/SwiftLintBugDemoApp/SwiftLintBugDemoApp/ContentView.swift
Linting 'ContentView.swift' (1/1)
/Users/jeremy/dev/xcode/SwiftLintBugDemoApp/SwiftLintBugDemoApp/ContentView.swift:13:9: warning: Redundant Discardable Let Violation: Prefer `_ = foo()` over `let _ = foo()` when discarding a result from a function. (redundant_discardable_let)
Done linting! Found 1 violation, 0 serious in 1 file.

Environments

  • SwiftLint version: 0.46.2

  • Installation method used: Homebrew

  • Paste your configuration file: N/A - default settings were used.

  • Nested configurations are not being used.

  • Xcode version: Xcode 13.2 Build version 13C5066c

  • Running the command: swiftlint lint --path /Users/jeremy/dev/xcode/SwiftLintBugDemoApp/SwiftLintBugDemoApp/ContentView.swift --no-cache --enable-all-rules produced the following output:

/Users/jeremy/dev/xcode/SwiftLintBugDemoApp/SwiftLintBugDemoApp/ContentView.swift:12:5: warning: Explicit ACL Violation: All declarations should specify Access Control Level keywords explicitly. (explicit_acl)
/Users/jeremy/dev/xcode/SwiftLintBugDemoApp/SwiftLintBugDemoApp/ContentView.swift:11:1: warning: Explicit ACL Violation: All declarations should specify Access Control Level keywords explicitly. (explicit_acl)
/Users/jeremy/dev/xcode/SwiftLintBugDemoApp/SwiftLintBugDemoApp/ContentView.swift:21:5: warning: Explicit ACL Violation: All declarations should specify Access Control Level keywords explicitly. (explicit_acl)
/Users/jeremy/dev/xcode/SwiftLintBugDemoApp/SwiftLintBugDemoApp/ContentView.swift:20:1: warning: Explicit ACL Violation: All declarations should specify Access Control Level keywords explicitly. (explicit_acl)
/Users/jeremy/dev/xcode/SwiftLintBugDemoApp/SwiftLintBugDemoApp/ContentView.swift:11:1: warning: Explicit Top Level ACL Violation: Top-level declarations should specify Access Control Level keywords explicitly. (explicit_top_level_acl)
/Users/jeremy/dev/xcode/SwiftLintBugDemoApp/SwiftLintBugDemoApp/ContentView.swift:20:1: warning: Explicit Top Level ACL Violation: Top-level declarations should specify Access Control Level keywords explicitly. (explicit_top_level_acl)
/Users/jeremy/dev/xcode/SwiftLintBugDemoApp/SwiftLintBugDemoApp/ContentView.swift:13:9: warning: Redundant Discardable Let Violation: Prefer `_ = foo()` over `let _ = foo()` when discarding a result from a function. (redundant_discardable_let)
Done linting! Found 7 violations, 0 serious in 1 file.
import SwiftUI

struct ContentView: View {
    var body: some View {
        let _ = 10 // This line triggers a violation.

        Text("Hello, world!")
            .padding()
    }
}

jeremypearson avatar Feb 15 '22 00:02 jeremypearson

Thanks for the report. It should be possible to check to see if we're in a result builder.

jpsim avatar Mar 09 '22 20:03 jpsim

@jpsim you're welcome!

Do you think it would be a good idea to temporarily suppress the autofix-support for this rule and/or temporarily change it from being an opt-out rule to being an opt-in rule, just until this bug is fixed?

Perhaps such temporary changes would cause more problems than they're worth though. What are your thoughts :)?

jeremypearson avatar Mar 10 '22 09:03 jeremypearson

Perhaps such temporary changes would cause more problems than they're worth though

That's my thoughts on this. I suggest you disable the rule with // swiftlint:disable comments where you're encountering this until we find a resolution.

jpsim avatar Mar 16 '22 15:03 jpsim

@jpsim Thanks. I've already opted to disable the rule by adding it to my disabled rules list in my config file, as in my projects, whenever I have a let _ = <expression> it's usually in an @ViewBuilder-annotated computed property variable - but for say, non-SwiftUI projects, I'd probably prefer to disable it in each individual case via // swiftlint:disable comments as you've recommended :).

jeremypearson avatar Mar 16 '22 18:03 jeremypearson

Did anyone make any progress in detecting a builder context? I'm having this problem as well, and we are separately having this problem in Muter.

ZevEisenberg avatar Oct 13 '23 15:10 ZevEisenberg