I think the way Rust checks borrows also makes it a lot more feasible to avoid allocations/copies; not because it is impossible to do in C, but because doing it in C requires writing very careful documentation and the caller to actually read that documentation. In (safe) Rust this is all checked by the compiler such that libraries can leverage it without blowing their complexity budget.