realm / SwiftLint

A tool to enforce Swift style and conventions.
https://realm.github.io/SwiftLint
MIT License
18.66k stars 2.22k forks source link

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

Open jeremypearson opened 2 years ago

jeremypearson commented 2 years ago

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

import SwiftUI

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

        Text("Hello, world!")
            .padding()
    }
}
jpsim commented 2 years ago

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

jeremypearson commented 2 years ago

@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 :)?

jpsim commented 2 years ago

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.

jeremypearson commented 2 years ago

@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 :).

ZevEisenberg commented 1 year ago

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.