Xcode "Abort trap 6" and non-sensical compile error, maybe related to SE-0293

Xcode Version 13.0 beta 4 (13A5201i)

Please create a new iOS SwiftUI app project, change minimum target to iOS 15. Add a SwiftUI View file HierarchyList, paste my code into it.

I'm getting "Abort trap 6" when compile. Clear derived data, restarting Xcode do not fix the problem.

Then search for "Uncomment" and uncomment the struct to see this error:

Cannot convert value of type 'Binding.Element' (aka 'Binding<Data.Element>') to expected argument type 'Binding<Data.Element>'

So according to error message, the given type and the expected are the same but the compile "think different"?! :) :)

I am guessing this is due to SE-0293.

// https://gist.github.com/zntfdr/9d94cac84235f04f021cb6c7e8c1a1c5

// Original article here: https://www.fivestars.blog/code/swiftui-hierarchy-list.html

import SwiftUI

struct FileItem: Identifiable {
    var name: String
    var children: [FileItem]?

    let id = UUID()

    static let spmData: [FileItem] = [
        FileItem(name: ".gitignore"),
        FileItem(name: "Package.swift"),
        FileItem(name: "README.md"),
        FileItem(name: "Sources", children: [
            FileItem(name: "fivestars", children: [
                FileItem(name: "main.swift")
            ]),
        ]),
        FileItem(name: "Tests", children: [
            FileItem(name: "fivestarsTests", children: [
                FileItem(name: "fivestarsTests.swift"),
                FileItem(name: "XCTestManifests.swift"),
            ]),
            FileItem(name: "LinuxMain.swift")
        ])
    ]
}

struct HierarchyListDemo: View {
    @State private var data = FileItem.spmData

    var body: some View {
        HierarchyList($data: $data, children: \.children, rowContent: { $item in TextField("Edit", text: $item.name) })
    }
}



public struct HierarchyList<Data, RowContent>: View where Data: MutableCollection, Data: RandomAccessCollection, Data.Index: Hashable, Data.Element: Identifiable, RowContent: View {
    private let recursiveView: RecursiveView<Data, RowContent>

    public init(@Binding data: Data, children: KeyPath<Binding<Data.Element>, Binding<Data?>>, rowContent: @escaping (Binding<Data.Element>) -> RowContent) {
        self.recursiveView = RecursiveView(data: $data, children: children, rowContent: rowContent)
    }

    public var body: some View {
        List {
            recursiveView
        }
    }
}


// ๐Ÿคข๐Ÿ˜• ๐Ÿ‘‡๐Ÿ‘‡
// this version uses SE-0293 ForEach w/ @Binding closure parameter. This doesn't compile
// Uncomment this to see compile error that doesn't make sense
//private struct RecursiveView__<Data, RowContent>: View where Data: MutableCollection, Data: RandomAccessCollection, Data.Index: Hashable, Data.Element: Identifiable, RowContent: View {
//    @Binding var data: Data
//    let children: KeyPath<Binding<Data.Element>, Binding<Data?>>
//    let rowContent: (Binding<Data.Element>) -> RowContent
//
//    var body: some View {
//        ForEach($data) { $item in       // ๐Ÿž๐Ÿž compile error: Cannot convert value of type 'Binding<Data>.Element' (aka 'Binding<Data.Element>') to expected argument type 'Binding<Data.Element>'
//            if let bindingToChildren = Binding($item[keyPath: children]) {
//                DisclosureGroup(content: {
//                    RecursiveView(data: bindingToChildren, children: children, rowContent: rowContent)
//                }, label: {
//                    rowContent($item)
//                })
//            } else {
//                rowContent($item)
//            }
//        }
//    }
//}



// the above do not compile, so use ForEach(.indices, ...) instead
private struct RecursiveView<Data, RowContent>: View where Data: MutableCollection, Data: RandomAccessCollection, Data.Index: Hashable, Data.Element: Identifiable, RowContent: View {
    @Binding var data: Data
    let children: KeyPath<Binding<Data.Element>, Binding<Data?>>
    let rowContent: (Binding<Data.Element>) -> RowContent

    var body: some View {
        ForEach(data.indices, id: \.self) { index in
            if let bindingToChildren = Binding($data[index][keyPath: children]) {
                DisclosureGroup(content: {
                    RecursiveView(data: bindingToChildren, children: children, rowContent: rowContent)
                }, label: {
                    rowContent($data[index])
                })
            } else {
                rowContent($data[index])
            }
        }
    }
}


struct HierarchyList_Previews: PreviewProvider {
    static var previews: some View {
        HierarchyListDemo()
    }
}

@hborla ?

You're right that the error message is bogus! That should be fixed by [5.5][CSApply] Always map types out of context when setting interface types for wrapped closure parameters. by hborla ยท Pull Request #38480 ยท apple/swift ยท GitHub

I'm not sure about the crash without more information, but I'll test out the code you wrote here to see if I can reproduce it.

1 Like

Updating to XCode 13.4.1 fixed this for me