When did it become allowed to witness a public protocol requirement with an `@_spi` declaration?

it has always been my understanding that @_spi things cannot witness protocol requirements unless that protocol is also restricted to that same @_spi.

and yet this compiles

public protocol FrostflakeProtocol {
    init(rawValue: UInt64)
}
public struct FrostflakeDummy {
    public let rawValue: UInt64
    @_spi(OrgPrivate) public init(rawValue: UInt64) {
        self.rawValue = rawValue
    }
}
extension FrostflakeDummy: FrostflakeProtocol {
}

which, when imported as a swiftinterface of a binary framework with library evolution, results in the strange situation where this is disallowed:

let id: FrostflakeIdentifier = .init(rawValue: x)

and this is also disallowed

extension IdentifierProtocol where Self == FrostflakeIdentifier {
    public init(_rawValue: UInt64) {
        self.init(rawValue: _rawValue)
    }
}

but this is allowed

extension IdentifierProtocol {
    public init(_rawValue: UInt64) {
        self.init(rawValue: _rawValue)
    }
}

let id: FrostflakeIdentifier = .init(_rawValue: x)

is this expected behavior?

Looks like a bug.

5 Likes

SwiftUI has been hiding the body property of various built-in views for years, and I’ve assumed it was by using _spi on them.

Yes, it’s a bug. It’s just one more dimension that we need to check during conformance checking but currently don’t. The post title asks “when” this became allowed, but I’m pretty sure this bug has existed since @_spi was implemented.

1 Like