Xcode 14 RC: "Cannot specialize protocol type"

Hello,

I have just updated to Xcode 14 RC (14A309), after weeks of peaceful relationships with previous betas, all benefits of primary associated types look like they're gone :fearful:

// ❌ Cannot specialize protocol type 'Collection'
extension Collection<MyType> { ... }

// ❌ Cannot specialize protocol type 'Sequence'
func foo(_ x: some Sequence<String>) { ... }

Is there anything obvious I miss???

3 Likes

For development with the macOS Ventura SDK, continue to use Xcode 14 beta 6.

If you’re developing for macOS, you won’t be able to use some of Swift 5.7’s features with Xcode 14 RC. Since macOS Ventura release is delayed, the macOS SDK bundled with Xcode 14 RC is still macOS 12.5.

1 Like

Thank you @stevapple, but I do not understand at all.

I've been running this code for several weeks on 12.5 Monterey. Are you telling that those features require a Ventura runtime? And I have been fooled for weeks of work despite the MACOSX_DEPLOYMENT_TARGET set to 10.13 and no error?

3 Likes

How am I supposed to ship a library that BOTH support primary associated types, some and any everywhere, AND macOS 10.13+?

I thought requiring Swift 5.7+ would be enough.

Is there anyone able to give actionable advice, not just "you hold it wrong"???

2 Likes

I've been running this code for several weeks on 12.5 Monterey.

And on iOS 12.4 as well (simulator), without any problem. I have logically supposed this code didn't rely on OS-level features.

I'm completely lost.


My questions, for anyone in the Swift team who can understand where I talk from (as a library developer):

  • I want to use primary associated types and define protocols with primary associated types, opaque parameter types (some in parameter position), protocol specialization (eg any Sequence<String>, some Collection<some Foo>)
  • I can require Swift 5.7+
  • I must back-deploy to previous operating systems - iOS, macOS, tvOS, watchOS (because the code is not some demo, it's a reliable library with 7+years of faithful presence in the Swift ecosystem, and 400K+ clones/year)
  • What are my options?
1 Like

If you want to use features limited to a specific Stdlib runtime, you will need to use #if available/@available and constrain your code to the environment that supports that feature (in this case that would be iOS 16 and etc). Constraining it to a Swift version isn't enough (since that's the compiler version and not Stdlib runtime version).

As I understood it, the only runtime limited features of Swift 5.7 were string processing and runtime casting to specialized existentials. How is the new protocol syntax limited?

How is the new protocol syntax limited?

SE-0346 isn't but SE-0353 is. I think @gwendal.roue wants to take advantage of both features here.

Huh, that's now how I understood the limitation of 353. I thought extension Collection<Int> was just sugar for the existing extension Collection where Element == Int. How are those two different?

extension Collection<Int> is SE-0346 so I think it should be fine here.

It's not, as pointed out in the OP.

Does the use of these features limit back deployment as well?

Yes, it seems like a bug to me. According to SE-0346:

The new feature does not require runtime support and can be backward-deployed to existing Swift runtimes.

and the standard library added primary associated types in 5.7 that back deploy.

I can't tell you how bad, lonely, and helpless I feel.

1 Like

I swear I saw somewhere that the only deployment limited feature of 353 should be the runtime casting support but I can't find it.

I don't know if this is the answer, but I'll note that @stevapple didn't say "runtime"; they said "SDK". The standard library is part of the SDK (specifically, its swiftinterface). So if it really is the Swift 5.7 compiler using the macOS 12 SDK, it's using the Swift 5.6 standard library APIs.

8 Likes

How to use SE-0353 features? (Constrained Existential Types) - #7 by John_McCall I think you mean this?

1 Like

Ah, you're exactly right. It's somewhat surprising it doesn't include the new interface since you can back deploy, but I think that explains what we're seeing @gwendal.roue.

That makes sense, since Collection (and etc) didn't have a primary associated type in 5.6 as it was added in 5.7.

Yeah, new protocols work fine:

protocol Something<SomeType> {
    associatedtype SomeType
}

extension Something<String> {
    var value: String { "string" }
}

This builds just fine.

…now that I think about it, though, that error message should probably be tweaked now that primary associated types are a thing!

3 Likes