The difference is that they do it by putting everything on the heap and relying on a garbage collector to manage it.
Which doesn't work well for concurrency, especially when you need to mutate data. Everything will look like you did it right, right until the moment that it bombs out with a runtime error.
But it all goes away as soon as the stack frame exits, requiring a whole sub-language for managing lifetimes and borrowing.
When I first started with rust, those were a bit intimidating. But now? I barely notice it. The only time I ever have to really think about it is if I need to be zero copy for some reason, which I rarely need. And that generally comes in the form of thinking differently about how you pass references, particularly when it comes to returning references from a function, THEN you need to think about lifetimes, but even then, only a little. In 99% of the cases, it can be satisfied by doing nothing more than adding 'a to one of the references you brought in, as well as the one you pass out.
But I've gotten used to simply not returning pointers at all in most cases, and without resorting to e.g. clone, which I go out of my way to avoid, often times just to see if I can rather than for any performance gain.
Besides, it doesn't feel like a sublanguage to me at all, it just feels like annotating it. Rather, the sublanguage would be rust's macros, which I still haven't really mastered, though I have written a few.
That... has not been my experience. How often do you have to resort to a RefCell because, even though you know perfectly well that your mutable reference will only modify one field of an object that the immutable reference never looks at, the borrow checker isn't smart enough to figure that out?
Honestly? I haven't. The only time I've ever used refcell was because I had a vector of bytes that lived inside one particular enum variant, and I needed to periodically append to it to while parsing other data, which sometimes ended up in other variants of that same enum. Then after that particular struct was done, insert it into a btreemap, (thus transfering ownership) before later reading it again and moving the data out of that vector for serializing into a binary file. I don't know whether this would be memory safe without a refcell or reference counting, but it doesn't matter because the performance hit is basically nothing. Eventually I added concurrency to this code, and that rc refcell became an arc rwlock. Regardless, rust took all of the work out of having to analyze and re-analyze whether what I was doing was safe, while still being fast as hell.