Goroutines try to work as if they were regular blocking code with a stack for each goroutine (green thread), and rely on standard library function calls to pause them nicely instead of actually blocking the OS thread. To keep memory usage low, they use segmented stacks (tiny stack that grows as needed). C is not compatible with segmented stacks, and calls to blocking functions that don't cooperate with the green threads cause problems for all goroutines.
Rust used to have "goroutines" before 1.0, but it was removed from the language. Rust didn't want overhead of swapping stack when calling into FFI, and didn't want to rely on special standard library/runtime to handle goroutine multitasking.
Futures can make progress using regular threads and stack, so their code doesn't need special environment.
Future objects contain all the state that needs to survive between steps, so the runtime doesn't need to do any magic stack swapping to preserve their state.
Futures still require their own runtime (executor) and compatible async I/O functions to work gracefully, but that is just a library, not tied to the language runtime, so non-async code doesn't need to pay the cost of it.