You don't have to think C is sound or good to distinguish a disfavored API style from mathematical unsoundness. There are infinitely many type safe APIs and languages that are, despite their soundness, ugly and hard to use.
I think almost all (tech) arguments stem from simple disagreements and/or different assumptions made on the definition of a (subjective) term.
That's a bit weird? In Rust, if you have an thing that returns Result<String, String> that's still type safe, even though success and error types are the same.
I think I know what you want to express..
You might say it's in-band vs out-of-band error signalling?
These types are not the same:
Ok<String>
Err<String>Nit: the type constructor is `Result`: given two types `A` and `B` (not instances of those types, but actual types) it gives you a new type `Result<A, B>`.
`Ok` and `Err` are called "variants" and can be used to construct a new _instance_ of `Result<A, B>`.
Of course that breaks down, when the success type is also an error message, eg when you are looking up something in a catalogue of error messages.
Rust has no trouble with this, for exactly the reasons you line out.