swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
66.77k stars 10.29k forks source link

Failed to produce diagnostic for expression #65474

Open bisgardo opened 1 year ago

bisgardo commented 1 year ago

Description

I'm following the Scrumdinger tutorial, made a small error and got the error message:

[...]/DetailView.swift:8:25 Failed to produce diagnostic for expression; please submit a bug report (https://swift.org/contributing/#reporting-bugs)

Steps to reproduce

Try to compile the tutorial project as of having just added the "Edit" sheet, where the file DetailView.swift is:

import SwiftUI

struct DetailView: View {
    let scrum: DailyScrum

    @State private var isPresentingEditView = false

    var body: some View {
        List {
            Section(header: Text("Meeting Info")) {
                NavigationLink(destination: MeetingView()) {
                    Label("Start Meeting", systemImage: "timer")
                        .font(.headline)
                        .foregroundColor(.accentColor)
                }
                HStack {
                    Label("Length", systemImage: "clock")
                    Spacer()
                    Text("\(scrum.lengthInMinutes) minutes")
                }
                .accessibilityElement(children: .combine)
                HStack {
                    Label("Theme", systemImage: "paintpalette")
                    Spacer()
                    Text(scrum.theme.name)
                        .padding(4)
                        .foregroundColor(scrum.theme.accentColor)
                        .background(scrum.theme.mainColor)
                        .cornerRadius(4)
                }
                .accessibilityElement(children: .combine)
            }
            Section(header: Text("Attendees")) {
                ForEach(scrum.attendees) { attendee in
                    Label(attendee.name, systemImage: "person")
                }
            }
        }
        .navigationTitle(scrum.title)
        .toolbar {
            Button("Edit") {
                isPresentingEditView = true
            }
        }
        .sheet(isPresented: $isPresentingEditView) {
            NavigationStack {
                DetailEditView()
                    .navigationTitle(scrum.title)
                    .toolbar {
                        ToolbarItem(placement: .cancellationAction) {
                            Button("Cancel") {
                                isPresentingEditView = false
                            }
                        }
                        ToolbarItem(placement: .confirmationAction) {
                            isPresentingEditView = false
                        }
                    }
            }
        }
    }
}

struct DetailView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationStack {
            DetailView(scrum: DailyScrum.sampleData[0])
        }
    }
}

The error is in line 56 (inside the second ToolbarAction), where the expression should have been wrapped in a Button.

Expected behavior

An error message explaining the actual problem (that the closure should return a Content value).

Environment

AnthonyLatsis commented 1 year ago
test.swift:33:69: error: type '()' cannot conform to 'View'
                        ToolbarItem(placement: .confirmationAction) {
                                                                    ^
test.swift:33:69: note: only concrete types such as structs, enums and classes can conform to protocols
                        ToolbarItem(placement: .confirmationAction) {
                                                                    ^
test.swift:33:69: note: required by static method 'buildBlock' where 'Content' = '()'
                        ToolbarItem(placement: .confirmationAction) {
                                                                    ^
test.swift:33:25: error: type '()' cannot conform to 'View'
                        ToolbarItem(placement: .confirmationAction) {
                        ^
test.swift:33:25: note: only concrete types such as structs, enums and classes can conform to protocols
                        ToolbarItem(placement: .confirmationAction) {
                        ^
test.swift:33:25: note: required by referencing initializer 'init(placement:content:)' on 'ToolbarItem' where 'Content' = '()'
                        ToolbarItem(placement: .confirmationAction) {

This is what happens with Swift 5.9-dev (c1d5118c21da49a), which is definitely an improvement, but still subpar.

A small example to reproduce this exact diagnosis:

import SwiftUI

let _ = ToolbarItem(placement: .confirmationAction) {
  _ = false
}