The versatility of Rust is quite impressive. Its looking like given a few years for these frameworks to mature, Rust could end up being a great job for just about every task.
Rust is both a low level but also a high level language. There aren't many mainstream languages that can go higher level than Rust with its traits, sum types, generics and macros. Haskell, Scala, maybe C++ to some degree, what else?
I don't think Kotlin is higher-level than Rust. It misses most metaprogramming features, and its generic programming capabilities are weaker (nothing remotely as capable as traits/implicits/type-classes).
I've said it misses most of metaprogramming features, not all of them. Reflection can't do the same things as macros can. Macros can transform arbitrary AST to arbitrary AST, reflection can't.
Similar thing with interfaces - while they serve the same purpose as traits, they are nowhere as flexible/expressive. E.g you cannot do blanket interface implementations - i.e. implement an interface for only the classes that implement another interface. You also cannot implement the same interface more than once, differing by generic parameters only. Or cannot define an interface with an associated type member (Scala is another language that can do it).
The discussion was about being higher-level vs lower-level. Rust is a more expressive language than Kotlin. Where languages are used is a different matter, because expressiveness is not the only thing playing role there. Politics and historical reasons are another dimension.
You seem to be missing my point. The point was not about which languages are mainstream (which is highly subjective, hard to measure and also may be an effect of certain politics), but about their level of abstraction. Rust is often placed in the "low level, close to the hardware" bin because it can go low-level very far if you wish to. But it is often forgotten that it can be also very high in terms of expressiveness / abstraction power and offers productivity features not found in many mainstream languages.
This is an old myth thats no longer fully true. Rust is a language that straddles both high level and low level in the sense that it is literally indistinguishable. You can use rust as if it were a high level language without knowing anything about low level stuff. The binary you get at the end, ends up being low level in the sense that it's performant as if it was written in a low level language.
There is definitely a mental overhead with rust but this has nothing to do with low level or high level concepts. The borrow checker is actually a high level feature that exists for safety, not performance.
> You can use rust as if it were a high level language without knowing anything about low level stuff.
How can you write that with a (I suppose) straight face? Rust makes you think about lifetime of every single variable, as anyone who's written a couple of lines of Rust knows... it' not just the lifetime annotations you will need when you get past the "copy everything" phase and start using or writing data structures, but the borrow checker making even the simplest stuff something you actually have to think through carefully (do you need to pass a reference, make a copy, use a mutable variation of some function, open a new block to limit the scope of the variable, assign it to a local variable to avoid it getting out of scope too early?). This is plainly "low level" stuff you need to worry about all the time which you just don't in any high level language.
These are high level safety features that replace another sibling high level construct: The garbage collector.
It's a different style of programming but still high level. Make no mistake the abstractions are high level but the cost is zero, hence the term zero cost abstraction and the association with "low level."