Skip to content

Passing a binding as a parameter without $ leads to SwiftCompile failed with nonzero exit code (Swift 5.10) #75416

Open
@Loradim

Description

@Loradim

Description

I created a simple custom (bottom) sheet as an extension to View to show (and close) a bottom sheet based on a @State variable (did this as the Botton sheet should be used at multiple Views, possibly trigged by a @State var show: Bool or a view model @Published var isShown: Bool)

extension View {
    func customBottomSheet(@Binding isPresented: Bool) -> some View {
        self.sheet(isPresented: $isPresented,
                   content: {
            Button("Dismiss") {
                isPresented.toggle()
            }
            .buttonStyle(BorderedProminentButtonStyle())
        })
    }
}

I thought I had to call this custom bottom sheet like this:

struct ContentView: View {
    @State var show = false

    var body: some View {
        VStack {
            Button("Tap me") {
                show.toggle()
            }
            .buttonStyle(BorderedProminentButtonStyle())
        }
        .padding()
        .customBottomSheet(isPresented: $show)
    }
}

but it results in this error message:
Error Message: Cannot convert value '$show' of type 'Binding<Bool>' to expected type 'Bool', use wrapped value instead

Suggested Fix (by Xcode - will create a separate ticket via Feedback Assistant for this) is: Remove the $

After applying this "fix", the compiler has a nonzero exit code

.customBottomSheet(isPresented: show) // Command SwiftCompile failed with a nonzero exit code

The correct, working code would be (not intuitive for me):

.customBottomSheet($isPresented: $show) // working

I'm not sure if the working code is the correct one by Swift language definition, but I wouldn't expect the compiler to exit without a meaningful error message.

If I can help with any additional information, please let me know!
~Heiko

Reproduction

import SwiftUI

extension View {
    func customBottomSheet(@Binding isPresented: Bool) -> some View {
        self.sheet(isPresented: $isPresented,
                   content: {
            Button("Dismiss") {
                isPresented.toggle()
            }
            .buttonStyle(BorderedProminentButtonStyle())
        })
    }
}

struct ContentView: View {
    @State var show = false

    var body: some View {
        VStack {
            Button("Tap me") {
                show.toggle()
            }
            .buttonStyle(BorderedProminentButtonStyle())
        }
        .padding()
//        .customBottomSheet(isPresented: show) // Command SwiftCompile failed with a nonzero exit code
//        .customBottomSheet(isPresented: $show) // Error Message: Cannot convert value '$show' of type 'Binding<Bool>' to expected type 'Bool', use wrapped value instead
                                                 // Fix: does remove the $, making this the first non-zero exit code error
        .customBottomSheet($isPresented: $show) // working
    }
}

#Preview {
    ContentView()
}

Expected behavior

I can't tell if the "working code" is the correct one by Swift language standards, but I would expect a meaningful error message from the compiler instead of existing with a nonzero code and no information.

Environment

swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    SwiftUIFlag: Involves SwiftUIbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.diagnostics QoIBug: Diagnostics Quality of ImplementationexpressionsFeature: expressionsproperty wrappersFeature: property wrapperstype checkerArea → compiler: Semantic analysistype inferenceFeature: type inference

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions