* It's very difficult to predict allocation patterns in C++ (even modern variants) from just the source code. An innocent looking object allocated on the stack might have a nontrivial constructor with all kinds of side effects. Rust, while being slightly less explicit than C, is much more explicit than C++.
* Modern C++ doesn't actually play that nicely with C. C++'s aliasing rules and casting rules keep getting more and more strict, whereas kernel programming lends itself to a lot of "bag-of-bytes-to-struct"-style programming. It would be very unfortunate if adding a C++ compiler to the kernel's build broke pre-existing C code by detecting UB in the context of C++ and decided to simply erase it.
And, Rust has even more incompatibilities with fast-and-loose C memory use. There are reasons why C and C++ compilers have "sanitizer" modes. Those identify places where code would be surprisingly elided. Yes, C has those too.
These 4 things do not happen invisibly in rust:
code running on struct creation (it will be an explicit ::new() call)
code running on struct copying (it will be an explicit ::clone() call)
code running on struct moving (moving is always a memcpy in rust, no custom code can run).
Error handling flow control (no exceptions, error handling will at minimum be marked with a '?'). (yes panic exists but this is basically for the same purposes as a kernel panic).
Rust favours making things explicit, much more so than C++.
In general, Rust is more implicit than C, but significantly less implicit than C++. Moreover, the ways in which Rust is implicit are more consistent and less likely to introduce bugs.
As an anecdote: I had a codebase where a nontrivial constructor contained a “registry” of created objects, for introspection. The design contract for that part of the API included the assumption that all constructions would be explicit, but it wasn’t actually enforced. Later, someone did some subclassing and added some APIs that inadvertently performed a converting construction, resulting in broken invariants around offsets and members in the registry.
Was it a good design? No, it was terrible. But nothing stopped someone from writing it, and the codebase otherwise “did everything right” (C++11, warning flags out the wazoo, fuzzing, unit tests, etc.)
It was a real pain in the ass to debug, and it fundamentally couldn’t have happened in a Rust codebase. And that’s just one tiny corner.
Code written to assume it will only ever run in context X being made to run in context Y instead is a problem that happens in every language equally. It is prevented by making a predicate Z to report whether X, and asserting Z where it matters. It is not a product of conversion.
In Rust, you would have had a factory function for type A, and somebody would have made a factory function for B that called the one for A, provoking the same failure.
We still need evidence of the original claim that implicit argument type conversion is a common source of memory corruption. We already know that bad design breeds bugs.
In Rust, the closest thing would probably be a shared Rc member for the registry and a non-owning indexing scheme (either weak references or something symbolic). But I’ve never actually seen a Rust codebase that needed to apply the registry pattern; it’s usually the wrong abstraction, like I said.
Edit: And no, replicating this pattern in Rust would not have produced the same failure. The failure mode in C++ resulted in exploitable memory corruption.
Specifically (and this is no longer quite eli5), Rust's freestanding mode--working without a standard library--is somewhat fuller and more fleshed out than the C++ freestanding mode.
Now, the sibling comment that points out that C++ gained a bad reputation pre-C++11 is probably a bigger reason for it not being seriously considered whereas Rust is, but there are some technical reasons where Rust does better than C++.
[1] Comparison of memory safety of c vs Zig vs Rust (from elsewhere in the comments): https://www.scattered-thoughts.net/writing/how-safe-is-zig/