As far as I know, D does not have ADTs (algebraic data types, a.k.a. tagged unions, a.k.a. Rust enums). I see that it has "enums" and "unions", but neither of these appear to be ADTs if I'm reading them correctly. And Rust's borrow checker can give very strong guarantees that aren't present in any other mainstream language that I'm aware of. In Rust, you can pass mutable references to large data structures between th…
> The cost of this borrow checker is huge: every reference in every program needs to be annotation with whether it's shared or mutable No. You need to "annotate" a mutable binding since bindings are immutable by default. But that also means that immutable bindings (ie the vast majority) does not to be "annotated". And even when you do need to, you literally just add the keyword `mut` as in `let mut foo = 42;`. > and…
EDIT: What's really relevant is that you can look at a Rust type, and tell whether it's shared, mutable, or owned; this is what Rust's borrow checker derives its power from. Likewise, Haskell's type system derives its (equally amazing) powers from the fact that you can look at a Haskell function's type signature, and tell what kinds of side effects it has. (Sometimes people think that Haskell functions don't have side effects in the sense that they never mutate anything. This is wrong; Haskell has mutable arrays in its standard library. Rather, it's that all side effects are reflected in a function's type signature.) https://hackage.haskell.org/package/array-0.5.4.0/docs/Data-...
I write Rust code for work, and we have a large codebase. We manage it pretty well, but there are definitely still innocuous looking changes that require adding lifetime annotations all over the place to avoid confusing error messages.
Rust is my favorite language by far (I get the impression you like it too and are defending it). I think the costs of its borrow checker are worth it, but they are significant costs.