It's been years since I've been programming Rust, and I haven't touched it a ton, but it does itch to try it out one day. I think the memory ownership/borrowship is a very interesting concept, but I'm sure it will take some adjustment to learn the new design patterns to become fluent in writing code and implementing anything you want.
I've not used Rust but it has been on my radar for years - because it is one of the few which directly addresses a modern challenge: multicore/processor applications. (Ditto Go, at a different level)
How successful the own/borrow concept will be is still being determined, but it is a useful advance over languages whose designers explicitly stated that threading is a library issue 
My bet is that it will be useful, and programmers will have to use higher level infelicities to screw things up. (Compare and contrast with a structured procedural language vs assembler)
I have started to tinker with it on some toy projects of mine.
Not sure about its specific usefulness on multicore/multiprocessor systems, there it doesn't really bring anything that others don't do or make anything significantly easier. The ownership/lifetime/borrowing doesn't really help you much if you have race conditions due to shared state between threads, etc. - you still need synchronization/mutexes/etc. in some form, the language doesn't handle this for you. The same for ease of parallelization/vectorization of algorithms - Rust is about the same as C (i.e. there are threads and coroutines - and the rest is up to you) here.
However, what made me look at it in embedded context was the built-in support for the async/away style cooperative multitasking - that could make a lot of very common embedded problems simpler to deal with and without having to resort to an RTOS. Which is always a plus, especially in memory constrained situations.
I have managed to get some code working even on ATMega328 (good old Arduino Uno board) and then, of course, ARM is fairly well supported. Where there are rough edges is the very immature ecosystem where there simply aren't as many packages ("crates") available and what is available are often one-man projects with little support and frequently abandoned. Hardware support often means you get the CPU core supported, code compiles and runs on the chip - but any peripherals beyond the basics like GPIO are up to you to implement drivers for.
To a lesser degree this is true even for desktop programming with Rust - e.g. I needed 0MQ implementation, there are about 3 out there, one is abandoned, the other is an alpha version that doesn't support what I needed and the third is a buggy mess. But at least there was something out there - if you need something more demanding or more niche, tough luck. Rust has interop with C and it is possible to make even C++ code work with it with some effort but it is far from seamless. And if you are jumping through the hoops to talk to C++ - then why bother with Rust?
So while there are plenty of "rustaceans" that will sing odes to the memory safety and similar things, the reality is that if your use case doesn't fit into the (fairly small) niche where there is good library support already, the language and ecosystem aren't going to be of much use to you. I don't see it replacing C or C++ any time soon, exactly for these reasons. Even the best programming language is of no use when you can't solve your problem with it.
Concerning the language itself, I am a bit on the fence with the syntax - I am a Python/C/C++/C# guy, so I am used to some pretty weird and "noisy" syntax. However, Rust feels a bit like the language syntax hasn't been designed but "grown" - "Oh, crap, we didn't think about this, let's make the programmer write an apostrophe here and there to indicate this!" And that despite that there is no formal standard out yet and the language is still pretty new (~10 years) and still in flux.
Worse, a lot of this "noise" comes from very low-level implementation detail boilerplate that "leaks" out and the user is forced to deal with it explicitly - like annotating the variable lifetimes. In some cases the compiler can infer it but in many it can't, which kinda sucks and leads to "line noise" statements like:
fn f<'a, 'b>(s: &'a str, t: &'b str) -> &'str {...} (that's a function taking two string arguments by reference with different lifetimes annotated by those 'a and 'b annotations and returns a reference to another string)
It is certainly not the worst stuff I have seen and I get why it is necessary for the compiler to know this - ever shot yourself in the foot by operating on a pointer/reference to a temporary that has been destroyed in the meantime? This is what the lifetimes are trying to address in Rust. However, the way it is done is really ... meh. A bit of wasted opportunity to design a language that isn't "write only" here, IMO. Of course, C++ is much worse in this regard - but C++ is also 40 years old and carries a lot of historical baggage with it.