SE-0426: BitwiseCopyable

I think the "marker protocol" concept hasn't completely stood up as a general idea. We should move away from talking about whether protocols are "marker protocols" and instead be explicit about the language properties we want from them.

SE-0302 defined marker protocols as having four key properties:

  • They cannot have requirements of any kind.
  • They cannot inherit from non-marker protocols.
  • A marker protocol cannot be named as the type in an is or as? check (e.g., x as? Sendable is an error).
  • A marker protocol cannot be used in a generic constraint for a conditional protocol conformance to a non-marker protocol.

That was defined in the context of Sendable, where we had a bunch of specific constraints:

  • Sendable doesn't need function or associated type requirements.
  • Sendable conformances are very common and shouldn't impose significant runtime overheads.
  • Sendable needs to not rely on runtime or type-specific support to avoid a back-deployment nightmare.
  • Sendable needs to be addable retroactively to a type in order to solve practical problems with pre-concurrency library dependencies.

So the restrictions were built around neither needing nor wanting any runtime representation of Sendable conformances because it'd be too heavyweight and would make clients too reliant on cooperation from their dependencies.

For BitwiseCopyable, we still definitely don't want to pay for unnecessary witness tables for every conformance, but we already have a (much more lightweight) runtime representation that's (AFAIK) perfectly reliable in back-deployed cases. The only questions with back-deployment are representing the BitwiseCopyable constraint itself and having some direct runtime support for querying it in e.g. dynamic casts.

So I think we want a somewhat different concept here. As I understand it, we're already building out some very similar runtime support for Copyable.

11 Likes