Rust could conceivably have worked similar to C, where you have to cast void* to the correct type. You could still have borrowing annotations on such generic pointers, similar to how C(++) has const. Having borrowing semantics doesn’t necessarily imply a general-purpose generics feature. Stuff like iterators and option types would obviously be different then.