4 ms·
The issue is that `~Copyable` is basically an anti-protocol. With a generics definition like `some Drinkable` you are _restricting_ the set of suitable types (
by Dagonfly 2y ago
The issue is that `~Copyable` is basically an anti-protocol.
With a generics definition like `some Drinkable` you are _restricting_ the set of suitable types (from any type to only the ones implementing `Drinkable`) which then _expands_ the available functionality (the method use() becomes available). From the perspective of type `Water`, it's conformance to `Drinkable` expands the functionality.
The language designers then get in a pickle if some functionality was assumed to exist for all types (e.g. `Copyable`)! By "conforming" to `~Copyable` you are _removing_ functionality. The type can NOT be copied which was assumed to be universally true before. Now, a generics definition like `some ~Copyable` actually _expands_ the set of suitable types (because Copyable types can be used as if they were non-copyable) and reduces the available functionality. It's the inverse of a regular protocol!
It becomes extra confusing if you combine `some Drinkable & ~Copyable` where `Drinkable` and `~Copyable` work in opposite directions.
This problem also exists in Rust. `Sized` is a trait (aka protocol) that basically all normal types implement, but you can opt-out by declaring `!Sized`. Then, if you actually want to include all types in your generics, you need to write `?Sized` (read: Maybe-Sized).