Simply changing property name from title to anything else cause compile error in another part of my code

I have an enum with this property:

enum Symbol {
    var title: String {   // change this to something else cause compile error in another part of my code
    }
}

in another part of my SwiftUI code:

ForEach($tabs) { $animatedTab in    // Cannot convert value of type 'Binding<[AnimatedTab]>' to expected argument type 'Range<Int>'

change back to title, compile error is gone.

I'm using Xcode 15.0

I don't understand why this is so.

My code: GitHub - mattyoung/Strange-Compile-Error

Does it still happen if you do a clean build? Swift still has some nasty incremental build bugs that look like that.

Clean build did not help. This only happen in my code I'm working on. If I reduce it to just ForEach(, problem is gone.

So strange. Wish I can understand.

When it works with the property name to title:

When the property name is changed from title to description:

And what if you go ahead and also fix tabSymbol.title to tabSymbol.description? Wouldn't be the first time the compiler gets confused and throws an unrelated error at you.

You are right! That fixed the problem. So the compile error is at that wrong place. This could be due to how ViewBuilder work or some kind of compiler bug?

I did try to use Refactor/Rename to change the property name but Xcode refactor failed.

I'd call it a bug in the sense that this error message is totally unhelpful for solving the 'real' underlying issue which seems like it could have been arbitrarily distant from the error location. I've definitely experienced this more with SwiftUI where the compiler gets confused typechecking the monster expressions that view body properties end up containing.

5 Likes

I have had similar experiences recently. Below is a very simple example, where error locations are marked with (1), (2), and (3).

ForEach (filteredRegions) { region in // (1)
    NavigationLink {
        RegionDetail (region: region) // (2)
    } label: {
        Text (region.name)            // (3)
    }
}

// (1) Cannot convert value of type '[Region]' to expected argument type 'Binding<C>'
//     Generic parameter 'C' could not be inferred

// (2) Cannot convert value of type 'Binding<C.Element>' to expected argument type 'Region'

// (3) Initializer 'init(_:)' requires that 'Binding<Subject>' conform to 'StringProtocol'

Can you guess what is causing these errors?

I scratched my had several hours, trying to figure out what is causing them.

The real culprit is sitting on this line:

Text (region.name)            // (3)

region didn't have a name property.

I am wondering what causes the compiler not to say so in this instance.

2 Likes

Someone knows the Swift compile would know. Iā€™m guessing something to do with ViewBuilder.