The ~Sendable is suppressing a conformance and hence it shouldn't be possible to state a conformance to Sendable and at the same time suppress it.
Try the same thing with BitwiseCopyable. Below, S would have BitwiseCopyable inferred since it's internal and its members are all BitwiseCopyable, but if you suppress the inference, you can't put it back:
struct S: ~BitwiseCopyable {
var x: Int
}
extension S: BitwiseCopyable {}
// ^ error: cannot both conform to and suppress conformance to 'BitwiseCopyable'
For a concrete type, "suppressing the inference" is the same as "not conforming" because it's the only way to spell that. ~P on a concrete type does mean "does not conform to P", unlike <T> where T: ~P for generic parameters which just means "is not required to conform to P (but still could)".
It’s actually the same idea though, because for a generic parameter, there is an implicit T: P unless you suppress it with T: ~P, when P is one Copyable and Escapable.
Sendable is a bit different because we don’t automatically conform generic parameters to Sendable, only nominal types (and only when they’re not public), but it’s still consistent with that idea.
As for whether to allow explicit Sendable conformance from an extension when it’s been suppressed on the type, this was discussed in the threads for Copyable as well. At the end of the day it’s an arbitrary choice. On one hand, banning the re-statement requires extra logic in the compiler, on the other hand, it's probably better stylistically if we don't allow it.
I will note that we allow this though, where the Copyable conformance is conditional:
struct G<T: ~Copyable>: ~Copyable {}
extension G: Copyable where T: Copyable {}
Furthermore, this works either way: if you omit the ~Copyable from the nominal type's inheritance clause, the extension still supersedes the implied unconditional Copyable conformance. So for maximum consistency, ~Sendable should work the same way, and we should allow this:
struct G<T>: ~Sendable {}
extension G: Sendable where T: Sendable {}
I see, I should have tried Copyable too because BitwiseCopyable bans this kind of conditional extension. I'll look into enabling that.
This flag now supports
~Sendableand has been turned into a diagnostic group that is disabled by default -ExplicitSendable, and can be enabled by-Wwarning ExplicitSendable.
Hi. Is ExplicitSendable diagnostic group available in Swift 6.2?
I saw this from the diagnostic document site: Documentation which seems like an update from a recent commit.
I’m excited about this feature. However, I cannot get it to work.
swift build -Xswiftc -Wwarning -Xswiftc ExplicitSendable shows warning: unknown warning group: 'ExplicitSendable'
And in a Package, .swiftSettings: [.treatWarning("ExplicitSendable", as: .warning)] has no effect.
Also tried with main-snapshot-2025-11-03 (the latest version I could get with swiftly install main-snapshot).
Unfortunately no, it’s only available on main branch snapshots. If you’d like to audit Sendable with 6.2 compiler you can use -require-explicit-sendable frontend flag.
Overall, +1 on this proposal. Would it be worth considering extending this proposal to all inferred conformances that are currently present in the compiler?
I'd like to see us make this syntax work the same way as it does for Copyable and Escapable as much as possible. The fewer nuances we have here, the easier it will be for new and existing Swift developers to understand what ~ means in a type. I realize this may require a new language mode to plumb through completely, but I hope that we can include that as part of the proposal.
Hi, thanks for the clarification!
One concern: the official diagnostics documentation already lists the ExplicitSendable group, but none of the publicly available toolchains support it, including the latest main-snapshot-2025-11-03, which I just checked again. This makes it appear as though the feature has shipped when it hasn’t and leads to unnecessary debugging on the developer side.
Would it be possible for the documentation site to indicate version availability, or avoid publishing main-only diagnostics until a matching toolchain is downloadable? This seems like something the Documentation Workgroup may want to help formalize.
Thanks again!
What is that documentation? I guess the problem here is that main snapshot might be lagging what gets published from main but this sounds like an infrastructure issue.
What is that documentation?
As my first reply:
I saw this from the diagnostic document site: Documentation which seems like an update from a recent commit.
Looks like it's indeed synchronization issue since it takes time to release a toolchain.
Are you thinking of Equatable, Hashable, and RawRepresentable?
Hi, @swift-documentation-workgroup members, please take a look. It appears that the diagnostic documents appear before the feature is available in Xcode or even the latest main-snapshot.
I think just Equatable and Hashable on enums which do not have payload cases:
enum E /* : Hashable */ {
case a
case b
}
This is inferred even if the enum is public, unlike Sendable.
RawRepresentable is implied if you state a raw type on your enum (enum E: Int) but it would be weird to state a raw type and then suppress the conformance (what would it even do?)
Hi Ethan,
For some of these documentation catalogs, that is indeed the case today - and the one generated with the Diagnostics that are hosted on docs.swift.org are included in that set. Today, that content is updated roughly nightly, using the content that's in the current main branch of the swift repository.
It's actually two workgroups that have been aware of this - both the documentation workgroup and the website workgroup, who have been working out how to address this (unfortunately longstanding) issue with all the content that's hosted and linked with swift.org.
We have some techniques that we believe will be able to sort out hosting versioned documentation, but the whole system to 1) map the content to versions and release it as such and 2) host that content in the infrastructure that supports Swift.org is all work-in-progress. It's been a topic in both workgroups, and the Information Architecture workgroup over the past several months, so if you're curious about the details, I'd be happy to help point you to them, or provide more specifics.
The gist of what we're aiming to do is build multiple sets of docs from both main and the current release branch, do the work to support selecting between two sets of versioned content (as that's not directly supported in the DocC infrastructure today) and tie that same process into the website redesign efforts, so that the documentation more seamlessly connects into the swift.org website content, both grow the space to contribute to documentation and consolidate where it lives with the recent docs proposal, and update the back-end processes to support generating this content and linking it into our release processes to support initially two versions of the content, growing to more as we iterate through releases going forward in order to establish a history of supported, versioned content.
In short, we definitely recognize it's a problem, it's a problem across our documentation that is linked from swift.org, it's been there for years, and multiple workgroups are engaged - actively working to solve it.
RawRepresentable gives you an Equatable/Hashable implementation that uses the rawValue instead of the enum discriminator. That can be undesirable e.g. for performance if the RawValue is a (long) String.
Are you suggesting that someone writing this:
enum E: String, ~RawRepresentable {
case a = "first"
case b = "second"
}
Would still get the synthesized init?(rawValue: String) and var rawValue: String, just not the conformance to RawRepresentable?
My initial thinking was that we wouldn't synthesize those requirements either, which would make the raw values pointless, but if we still synthesized those two APIs and just suppressed the conformance, I suppose I can see that still being defensible for some use cases.
Does the rawValue-based Equatable implementation have precendence over the Equatable implementation inherent to enums?
Yes exactly.
Yes.
overall the proposal makes sense and seems like an improvement in clarity and consistency to me. i have a few questions regarding the interactions between various inference rules. here's some sample code i've tested against the current main branch snapshot with the experimental feature enabled (Compiler Explorer):
protocol RefineSendable: Sendable {}
@MainActor
protocol GAITRefineSendable: Sendable {}
// MARK: -
@MainActor
class InferredFromGAIT: ~Sendable {} // allowed?
class InferredFromRefinedProto: ~Sendable, RefineSendable {} // 🛑 cannot both conform to and suppress conformance...
class InferredFromRefinedGAITProto: ~Sendable, GAITRefineSendable {} // bug?
actor A: ~Sendable {} // 🪲 bug!
// MARK: -
func takeSendable(_: some Sendable) {}
func g(
_ inferFromGAIT: InferredFromGAIT,
_ inferFromRefinedProto: InferredFromRefinedProto,
_ inferFromRefinedGAITProto: InferredFromRefinedGAITProto,
_ act: A,
) {
takeSendable(inferFromGAIT) // 🛑 type does not conform to Sendable
takeSendable(inferFromRefinedProto) // 🛑 fails due to above error
takeSendable(inferFromRefinedGAITProto) // ✅ bug?
takeSendable(act) // ✅
}
i know there are various rules that imply Sendable for types marked with a global actor annotation, but it's not entirely clear to me what such interactions should be with respect to this feature. is it valid to mark a GAIT as ~Sendable (maybe it is per this, but idk if i've ever seen it in practice...)? if that is allowed, presumably the InferredFromRefinedGAITProto example above should still be diagnosed as requiring a both a conformance and its inverse.