Rust's affine (ownership) types add a lot of power. They make it possible for APIs to take ownership of a passed-in object and guarantee no other references to it exist. For example this lets you manually deallocate resources (e.g. close a File), while preserving the invariant that if you have a reference to a File, then it is open.
Also, Rust traits and generics are a lot more powerful than anything Java has. For example Rust generics support associated types. E.g. the Iterator trait has an associated type Item:
trait Iterator { type Item; ... }
You can now write code that's generic over Iterator, and refers to its Item type:
fn first<I: Iterator>(iter: I) -> I::Item { iter.next().unwrap() }
Toy example, but associated types are really important.
Rust traits and generics are more powerful in other ways too. E.g. in Rust you can do anything with a generic type, unlike Java where type erasure means you can't write 'new T' etc.
Well, except that Java went ahead and gratuitously complicated their type system with wildcards. That was crazy.
Rust traits are very much like Haskell type classes. Java gives you classic OOP, but neither Rust nor Haskell do.
Rust generics are much more like Haskell generics than Java generics. Rust and Haskell both have associated types, Java doesn't. Java generics are crippled due to type erasure; Rust and Haskell don't have those limitations.
Rust and Haskell generics support a lot of type-level computation; Java doesn't.
Rust and Haskell don't have ubiquitous nullable-by-default values; Java does.
Rust and Haskell have discriminated sum types; Java doesn't.
The only way I think Rust is more like Java than Haskell at the type level is that Haskell has higher-kinded types and Rust/Java don't. There are plans to fix this in Rust though.
Both Rusk and Haskell erase types at runtime. The difference is they don't rely on runtime reflection for anything, so it doesn't hurt them.
In Rust, each instance of a generic function is compiled separately and customized as necessary to the specific type parameters. You can write "let t = T::new();" because the compiler will generate a call to the correct constructor for each instance of the generic code. In this sense, types are NOT erased.
There's an interesting comparison of Rust and Haskell's type system here: https://www.reddit.com/r/rust/comments/4jh8hv/question_about... I guess it's just a matter of opinion about what sorts of differences you think are significant vs not.
As well, traits are quite a bit different than classes, but not always in a good way!
This isn't in keeping with HN's guidelines[0], eg:
> Be kind. Don't be snarky.
Of course, you may be expressing an unpopular opinion, so your comment may receive downvotes regardless. You may wish to delete and repost without the first clause to more accurately gauge community response.