When a lot of what you're doing is interacting with low-level platform APIs, you end up having a lot of those unmanaged objects. After a certain point, the upsides of using a GC kind of disappear because you still have a lot of places you have to worry about those objects.
Of course, this can be worked around by providing managed wrappers around those unmanaged object, but at a certain point, it becomes easier to just drop down to an unmanaged but safe language (like Rust) that model the unmanaged resources more accurately. In my experience, it's somewhat easier to provide Safe Rust wrappers around your average Windows API than it is to provide a C# Managed Wrapper around the same.
---
And yes, go is special because it has very smol stacks, so doing any kind of FFI on it is a bad idea.
I'm genuinely curious as to what would make FFI in Rust easier than in C#, assuming an apples-to-apples comparison (i.e. use of "unsafe" and associated features in both cases"). Most complexity in P/Invoke shows up when you try to use it to automatically map data to managed data types; but in modern C#, you might as well just use raw pointers, stackalloc, spans etc.
...so requiring `use of "unsafe"` is often akin to forbidding Cargo/pip/NPM/etc. and then calling the language un-productive or faulting a procedural/imperative language for performing badly when you code as if you're writing Haskell.
https://www.hobofan.com/rust-interop/
https://areweextendingyet.github.io/
Using the ecosystem rather than reinventing it is a core tenet of Rust's value proposition.
Python to Rust is a pretty radical swing from one approach to language design to another. I'd expect you could solve most of the maintenance problems with Python by switching to something statically typed but with garbage collection (e.g., C#, Java, or go), without incurring the costs of moving to Rust.