Rebalancing coherence: potential late-breaking change

After looking over the crates, I think I will wind up with a revised version of the proposal that also includes an unstable attribute (unstable because this part of the design seems like something we will want to refine; but we can still use it in libstd as I describe below). Let’s call it #[fundamental] for now – it indicates types/traits that are so fundamental, that adding impls for them is a breaking change.

For types, #[fundamental] would mean “adding a blanket impl over this type is a breaking change”. &T and &mut T are automatically #[fundamental]. Box would also be tagged #[fundamental].

For traits, #[fundamental] would mean “implementing this trait is a breaking change”. The Fn traits would be #[fundamental], since it is common to want to overload on closures vs other kinds of values.

The nice thing about this attribute is that it is a relatively minimal commit. That is, it commits us to finding some mechanism that can be used to make Box and the Fn traits work this way, but it doesn’t have to be the attribute. It is also something we can add to other types/traits over time, because making a type fundamental just lets children implement more impls, which is always backwards compatible (but we can never take the attribute away).

My feeling here is that it is unclear what precise mechanism we want long term to go beyond the basic rules I proposed (or perhaps generalize them), but whatever mechanism it is, it will want to support the impls on Box and Fn I encountered. So it makes sense to put in something simple for now that gives us breathing room to experiment.

1 Like