IIUC, the fundamental difference between Go and Rust is that both make multi-threading a core feature of the language, but Go threads are shared-everything and Rust threads are shared-nothing. (Or very roughly in C terms, Go threads act like pthreads, and Rust threads act like fork.) Go encourages you not to program in a style where your threads stomp on each other's data-structures willy-nilly, but there's no protection built into the language itself. OTOH, AFAICT Rust doesn't even *have* mutexes, because it has safer ways to share state.
Personally this difference is enough to pretty much rule out Go as an option so long as Rust ends up being viable at all, no matter what other clever syntax and type systems and stuff they have... but of course YMMV.
> Rust also disallows null pointers, which I personally do not agree with. Maybe it's my background as a C programmer, but I like having a special value to represent "none." I always find myself using clunky workarounds to emulate NULL
I don't remember the details, but I'm pretty sure it's easy and idiomatic in Rust to define a "maybe<X>" type: a value which is either "none" or else has a real pointer-to-X in it. The trick is that unlike C, now you *can't* dereference such a pointer without checking for NULL-ness when "unpacking" it. This might seem like a burden, but of course it only applies to those pointers which *might* be NULL, which are exactly the ones that you have to check. So they're not trying to make this clunky; basically it's just like C, except now the compiler will keep track of when you need to check for NULL and when you don't. Boom, no more segfaults.
> Rust has this concept of "typestate," which is kind of like the Linux kernel's BUILD_BUG_ON or Boost's static_assert
Typestates are *substantially* more powerful than BUILD_BUG_ON, because typestates make compile-time assertions about program flow. A simple example of a typestate assertion would be "strings which come from the network and then later end up being passed to the filesystem *must* go through the utf8 sanitizer at some point in between". If you accidentally add a code path that violates this invariant, the compiler will tell you.
Generally a lot of things in Rust are designed around the idea a good language should help you write correct code.
(Disclaimer: Graydon's a friend, and I reviewed an early version of the Rust spec, but I haven't been involved or followed the project much since.)