I knew casting an NSMutableString to NSString to make it "immutable" would result in the same pointer, of course; that the compiler and any users of the NSString would see it as immutable, but that underneath it would still be mutable.
First, this test shows that aliasing can be a big problem in this case; that's something we should be cognizant of.
But calling mutableCopy on an NSString that under the hood knows it is already an NSMutableString returns a new NSMutableString instance. This makes sense: this isn't to avoid aliasing issues, but just because we explicitly asked for a copy.