Didn't mind the experience at all except for a few niggles which actually are nothing to do with the language itself and more just some of the community attitudes. Some of the evangelists are... less optimal.
IMO, Rust shares the same inner-simplicity that C has, but combined with ability to build and use bulletproof higher-level abstractions. The same way I roughly knew what machine instructions (roughly) my C code produces, I know what machine instructions my Rust code produces.
It is the equivalent of C++, not C. You can write code which you cannot guess the machine code, as soon as you use any of the abstractions, just like C++.
And, unlike most other languages I've seen, you can't just sit down and write a "bad" Rust program and then refine your abilities; the compiler won't let you do the "bad" things, so you have to get everything write from the word go.
In a sub-thread comparing language features of two languages to each other to compare their overall complexity, I think it pays to be precise.
Which is why I think it would be easier to learn, you get immediate feedback.
If you are a competent C programmer - the kind that "doesn't make" memory errors, you have to be manually keeping track of lifetimes and borrows.
Rust takes that mental effort and offloads it to the compiler.
Lifetimes and the borrow checker will likely be jarring for people coming from languages where you don't need to worry about memory allocation and ownership, but if you are coming from C or C++, you will likely find the borrow checker a relief (I did).
> the compiler won't let you do the "bad" things, so you have to get everything write from the word go.
And it's wonderful! Finding and fixing problems at compile time is the fastest and cheapest way to do it, and is also a productive way to refine your abilities.
I expect I'll run into more friction once I get to any point where I want to make more dynamically interlinked data structures, though that might also push my designs into directions that use fewer pointers and more indexes or other indirect references to start with (I'm not sure of that yet)—and I really like the idea that if I can pare some of it down to a working “core” data structure semantic that involves pointer juggling, I can put carefully constructed hard-packed blocks of the pointer juggling in their own unsafe zone and then not be able to accidentally break the invariants outside of that.
Which, again, is almost exactly the same thing I'd tend to do in C with inline wrapper functions and visibility stuff, and making sure I compute all the intermediary results in one phase and putting all the hard mutations in a second, unfailable (except possibly for hard crashes due to null pointers or such) phase so that if something goes wrong the data doesn't wind up crashing down to a persistent broken state from mid-flight!
Heck, I've even done the newtype pattern (single-element structs for safe reinterpretation/bounding of an underlying type) in C before!
I've described the way I write C as “as though I were hand-cranking the front end of a strict, low-level Haskell or Caml compiler in my head”. Rust is the closest I've seen thus far to moving a big chunk of that part of me into the digital part of the compiler. So I'm guessing my taste wasn't exactly uncommon.