I think part of the problem here is that Vec internally uses so much unsafe that it's a bad example â types should be trying to use as much of safe Rust as they can to reduce the amount of unsafe preconditions that they have to check.
Vec could be made much safer than it currently is, using more of the language's existing guard-rails. A Vec conceptually has two fields: a storage field of type Box::<[MaybeUninit<T>]>, and a length field that controls how much of the storage field is initialised. (There's nothing blocking Rust from changing to such a definition of Vec today â although there's a stable guarantee that a Vec consists of a pointer, a capacity, and a length, this layout fits that because &'static mut [MaybeUninit<T>] is a pair of a pointer and a capacity.) Ignore the opsem special case for Box here â it could be overridden if necessary (and will probably be changed anyway).
The invariant on such a Vec is that the storage field is initialised as far as the length, but no further.
When looking at this hypothetical Vec layout, it feels conceptually to me like the length should be unsafe but the storage shouldn't be, although I appreciate that this position isn't entirely consistent, so I'm trying to analyse why I feel that way. I think the reason is that the potentially unsound thing you can do with the storage (assuming it's initialised when it isn't) is an obviously unsafe thing that's already guarded by unsafe requirements (on <[MaybeUninit]>::assume_init_*) â so it's somewhat obvious that "swapping out the storage for a different slice" is an operation that requires care. It's less obvious that changing the length field will break the unsafe assumptions made by <[MaybeUninit]>::assume_init_*, so it's useful to have the language force changes to that field to add a safety comment acknowledging how the invariant is being maintained.
Notably, the pointer and capacity can't possibly get out of sync with each other â in this model, that's being checked by safe Rust's usual type checks and is not something that needs any unsafe assumptions at all. So the capacity is not an unsafe field in this model.