The whole bottom row represents a second way to write things already expressible by the top-right cell. We didn't bother to do that for the bottom-right row, so we already have this problem today:
extension Foo where T: Hashable {
func bar<U>(_: U) where T: Comparable {}
}
extension Foo where T: Hashable, T: Comparable {
func bar<U>(_: U) {} // could be equivalent to above, but isn't
}
SE-0267 exposes the problem in a lot more places, and while there's an obvious way to canonicalize the newly-allowed declarations to an existing syntax (bottom-left cell -> top-right cell*), we have both the top-right and bottom-right cells in existence today. So the options would be:
- Moving a constraint between the extension and the member is always breaking (as proposed).
- Moving a constraint between the extension and the member is okay if the member is not itself generic (still ABI compatible but a much more subtle rule).
- Moving a constraint between the extension and the member is always okay (ABI-breaking for instances of the bottom-right cell without extra annotations, in order to canonicalize them to the top cell).
* We can't canonicalize to the bottom-right cell because it's not obvious which constraints go on the extension and which go on the function. If it's "all of them that can go on the extension", that's the top-right cell. We could in theory canonicalize to the bottom-left cell, but that'd be extra breaking since it's the one cell that isn't possible today, and it loses some nice properties for partial names.