The semantics of base
are woefully ill-defined. Predictably, this has led to diverging behavior across the stdlib.
The correct thing to do, in my view, is for a mutable SubSequence
type to always preserve its entire base collection on mutations -- dropping the sliced-off parts is highly questionable behavior. (If I didn't care about preserving the rest of the collection, I would've simply copied the data into a new collection value instead of mutating the slice.)
Substring.append(contentsOf:)
got this badly wrong: in exchange for a performance boost, we got unusable semantics. I really want to fix this, but Hyrum's Law is in full effect for String
APIs, and that makes this a high-risk change.
Sadly, as far as I am aware, the behavior as implemented does not violate any documented requirement -- base
properties aren't part of any protocol, and there are no documented expectations about them.