I had some discussions about whether we want associated types to have a defaulting rule similar to what we devised for generic type parameter and extension declarations, where even if a protocol does not require Self: Copyable or Equatable, extensions and type parameters will require those protocols unless they explicitly suppress those requirements:
protocol Foo: ~Copyable { }
func foo<T: Foo>(...) // T still requires `Copyable` by default
func bar<U: Foo & ~Copyable>(...) // U is not required to be `Copyable`, explicitly
As Kavon's pitch notes, we can't extend this defaulting behavior to all associated types, at least with the type system features we have today, because a protocol with recursive requirements can have infinite associated types, and if all of those associated types were Copyable by default, it would be impossible to suppress all of those defaults. Nonetheless, the reasons for the defaulting rule for generic parameters seem potentially interesting for associated types as well:
- The defaults maintain "progressive disclosure", where code that does not explicitly traffic in non-
CopyableorEscapabletypes is not required to grapple with ownership or lifetimes. - The defaults allow for source stability when retrofitting generalizations onto existing libraries, particularly the standard library, so that types like
Optionaland protocols likeEquatablecan (or will be able to) generalize to work with non-Copyableand non-Escapabletypes without affecting existing code.
Although we can't provide a blanket defaulting mechanism for all associated types, one idea that we've revisited from the original SE-0390 discussions is the idea of allowing the protocol declaration to control what associated types, if any, have defaulting behavior. I added some discussion to the proposal with a few shapes of how this might look:
However, in discussion with the standard library team and a few other developers, we haven't identified a place among ourselves where we would definitively need such a feature. The standard library protocols that are good candidates for generalization, such as Equatable, Hashable, and Comparable, don't have any associated types, and the Sequence/Collection series of protocols is likely to benefit from deeper changes to make efficient use of ownership and lifetimes, so there are likely to be new protocols to handle their generalization anyway. But I wanted to hear from the community here as well: would you make use of an associated type defaulting feature if it were available?