logoalt Hacker News

kccqzytoday at 1:04 AM2 repliesview on HN

> A is a subtype of B then `Vec<A>` is a subtype of `Vec<B>`

That’s just not true. Java would permit it but then you get ArrayStoreException so this is unsound from a type system perspective. To make this sound, we need to classify each use of a type parameter to be covariant, contravariant, or invariant.


Replies

jkhdigitaltoday at 3:54 AM

Java doesn’t permit that. You must specify covariant or contravariant type parameters with <? extends T> or <? super T>.

i2talicstoday at 4:41 AM

You are misled for two reasons.

First of all, Rust isn't subject to the same soundness issue as Java precisely because of the Rust's ownership semantics. You can't produce the ArrayStoreException issue because you can't mutably alias a Vec in the first place. To be more precise, &mut T is invariant, but Vec<T> is covariant (in T).

Second of all, Rust already does classify the co/contravariant status of all of type parameters. If you've ever tried to omit a type parameter from the fields of a struct and find that you're forced to insert a "PhantomData" value, this is because the entire purpose of PhantomData is to imply what variance classification the compiler should give the type parameter.