In my opinion, it's the initialization part of RAII which is really powerful and still missing from most other languages. When implemented properly, RAII completely eliminates a whole class of bugs related to uninitialized or partially initialized objects: if all initialization happens during construction, then you either have a fully initialized correct object, or you exit via an exception, no third state. Additionaly, tying resources to constructors makes the correct order of freeing these resources automatic. If you consume all your dependencies during construction, then destructors just walk the dependency graph in the correct order without you even thinking about it. Agreed, that writing your code like this requires some getting used to and isn't even always possible, but it's still a very powerful idea that goes beyond simple automatic destruction
This sounds like a nice theoretical benefit to a theoretical RAII system (or even a practical benefit to RAII in Rust), but in C++, I encounter no end of bugs related to uninitialized or partially initialized objects. All primitive types have a no-op constructor, so objects of those types are uninitialized by default. Structs containing members of primitive types can be in partially initialized states where some members are uninitialized because of a missing '= 0'.
It's not uncommon that I encounter a bug when running some code on new hardware or a new architecture or a new compiler for the first time because the code assumed that an integer member of a class would be 0 right after initialization and that happened to be true before. ASan helps here, but it's not trivial to run in all embedded contexts (and it's completely out of the question on MCUs).