To be honest, Rust having opaque handles is a pretty unimpressive demonstration of its power. If that's the main thing that code had to benefit from Rust, it would absolutely not be worth a massive new toolchain with increased memory requirements and longer compile times.
Obviously, programming language design hasn't stood still in the intervening years since C was created, but C had a lot of momentum and we don't just do massive rewrites for small incremental gains. IMO the only real reason why Rust has been compelling and stands out from most other options is the borrow checker. That's the thing that is truly compelling and that people have been enduring great pains for. However, it's asymmetrical; not all code is going to have very much to gain from the borrow checker, at which point any modern systems programming language and some older ones are similarly compelling. (Note that I'm not suggesting there isn't still benefits to having the guarantees of the borrow checker, especially if you really need memory safety guarantees... but many people don't necessarily, and some that do need even stronger guarantees like formal proofs.)
As far as opaque handles go, you could easily accomplish that with a subset of C++, or even with C (with an asterisk, but one that would not hinder a project like coreutils from doing so.) When talking about stuff like this we're not even really talking about C, but more coding standards that were prevalent with old UNIX and UNIX-like code. And sure, improving that is net gain, but it has little to do with the unique merits of Rust.
Outside of handles, the integer type situation in C is worse than Rust or really any modern programming language, but at least most modern code will cling fairly strongly to <stdint.h> types instead.
P.S.: I speak with relatively similar experience on both fronts, but I can't say the same about being particularly more confident contributing to Rust projects. It's not that it's particularly low, but 1. I don't find too many opportunities and 2. I have never found contributing to C/C++ projects to be that terrible, and I still do so occasionally.
Borrow checking makes the type system actually work, so this matters everywhere. Take Rust's Mutex<T>. You can (and people do) make such a type in C++. But in C++ the type's key feature - that you can't "forget" to take locks and release them - is destroyed by the lack of type safety, they have to ask you to please be careful not to break it, whereas in safe Rust you can't break it.
Google has an analogue of OwnedFd for C++ and again the language doesn't preserve type safety so they need to nag you to please not do all the so-easy things which will destroy type safety and make the type worthless. OwnedFd doesn't need to remind you about that.
Neither C nor C++ have niches, and so when they do attempt a Maybe type - which is very useful in system programming in my experience - it's significantly heavier than the integer handles programmers were used to instead, and of course this means people won't use it in these applications. Rust's Option<OwnedFd> is the same representation (a 4 byte integer type) as the C integer you'd have used, but with the same ergonomics as any other Maybe type, leading to improved safety despite same performance.
Also, I'd say the characteristic difference isn't technology like the borrow checker, but Rust's Culture, the technology is just enabling that culture.
Well of course it matters everywhere in Rust, the borrow checker is how Rust accomplishes those things. It is novel. It's an approach to memory and data-race safety that does not require a GC, and it has relatively low overhead.
The problem with move semantics in C++ is the lack of borrow checking, but simple programs (e.g. a lot of the coreutils realistically) very little transfers of ownership are actually needed, because the programs are just so relatively simple. Meanwhile, GC'd languages can usually ignore this altogether, at the cost of some overhead.
It's not just the borrow checker. One interesting way to see how much lifting is needed is to examine the "Circle C++" compiler. Sean Baxter's language / C++ experiments takes the same approach and you'll see Sean needed not only an equivalent to Rust's borrow checker, but its trait system (roughly equivalent to the Concepts proposal in C++ 0x, not the "Concepts Lite" which is modern C++ 20 Concepts) including Rust's auto traits Send and Sync, and a whole bunch of stdlib infrastructure.
If you try to do without Send and Sync you have to choose, either your language has data races and they induce UB (as in, say, Go and several popular garbage collected languages) or your language doesn't have real multi-threading. Rust needs these traits to be able to provide a data rate free safe language with multi-threading. Could other approaches exist? Well for one thing after Rust 1.0 there has been considerable work on theory and practice for Java-like loss of sequential consistency without UB. But there isn't today any good "This definitely just works" alternative. For a future Rust-like language, an industrialization of best practices, this is the best we currently know although it's reasonable to expect that one make a decade from now will have better options.
Obviously, programming language design hasn't stood still in the intervening years since C was created, but C had a lot of momentum and we don't just do massive rewrites for small incremental gains. IMO the only real reason why Rust has been compelling and stands out from most other options is the borrow checker. That's the thing that is truly compelling and that people have been enduring great pains for. However, it's asymmetrical; not all code is going to have very much to gain from the borrow checker, at which point any modern systems programming language and some older ones are similarly compelling. (Note that I'm not suggesting there isn't still benefits to having the guarantees of the borrow checker, especially if you really need memory safety guarantees... but many people don't necessarily, and some that do need even stronger guarantees like formal proofs.)
As far as opaque handles go, you could easily accomplish that with a subset of C++, or even with C (with an asterisk, but one that would not hinder a project like coreutils from doing so.) When talking about stuff like this we're not even really talking about C, but more coding standards that were prevalent with old UNIX and UNIX-like code. And sure, improving that is net gain, but it has little to do with the unique merits of Rust.
Outside of handles, the integer type situation in C is worse than Rust or really any modern programming language, but at least most modern code will cling fairly strongly to <stdint.h> types instead.
P.S.: I speak with relatively similar experience on both fronts, but I can't say the same about being particularly more confident contributing to Rust projects. It's not that it's particularly low, but 1. I don't find too many opportunities and 2. I have never found contributing to C/C++ projects to be that terrible, and I still do so occasionally.