> The facts that these exist and the programmer has to always be consciously be aware of it
This is what separates a systems programming language suitable for OS and embedded development from managed languages, which are not.
The complexity ultimately stems from unavoidable details of the hardware. Languages which do not offer similar representations will be incapable of making full use of the underlying hardware, including writing certain projects like bootloaders, firmwares, OSes, etc. Rust is pretty close to state-of-the-art in terms of providing reasonable abstractions over the hardware.
It sounds to me like you're used to managed languages with a runtime which are great for certain applications, but unable to be specific enough about memory layout, how data is formatted in memory, etc. for some tasks. Those choices were made for you by the language runtime's authors and necessarily limit the language's applicability to some problems. Rust, C++, and other systems programming languages don't have such limitations, but require you to understand more of the complexity of what the system is actually doing.
Any language which provides adequate representations for taking full advantage of the hardware is going to be on a similar order of complexity as Rust, C++, or other systems programming languages, because the hardware is complex. Managed languages can be nice for introducing folks to programming, precisely because much of the complexity is hidden in the runtime, but that can be a double edged sword when it comes time to approach a systems level task.
Instead of wishing the language didn't offer those representations, it may be more productive to ask why C++ and Rust converged on such similar ones. Exploration of that question will be enlightening.
There should be no such difference. The bigger problem is that OS's enforce this duality when in fact there should only be application level software and an absolutely tiny core to handle IPC and scheduling. This then allows you to enforce the boundaries between various bits far more strictly.
None of these have anything to do to do with memory layout or how data is formatted in the memory. You are arguing a different point than the one being discussed here.
These are fundamentally hacks around the compiler’s inability to understand ownership and lifetimes, at least the way Rust (and C++) are designed.
These exist in Rust because otherwise you would have to use unsafe blocks all the time to write any reasonable code.