@Gankra Good post.
Regarding capacity: Searching the standard library, I find:
-
foo.capacity() - foo.len()onVec<u8>in two places (libstd/sys/windows/pipe.rs,libstd/sys_common/io.rs), both as part of unsafe code that passes the uninitialized portion of theVecto OS read functions; -
foo.capacity() == foo.len()onVec<u8>in the samelibstd/sys/windows/pipe.rs, and onVec<T>inlibcollections/vec.rs. (In the latter case, capacity ≠ len is taken to mean that an element can be appended without reallocating.)
If capacity() returns 0, the first will overflow, and the second will allow out-of-bounds writes – both really bad. Of course, the stdlib itself can be changed, but external code may include similar logic. So I think capacity() returning 0 is unviable at least for Vec, and probably for String as well.
(But then, I agree that supporting statics in Vec is a bad idea anyway because of the cost on deref_mut; I didn’t think of doing it only for String.)
Also, nit: I don’t think any of pop, truncate, or clear would need to special-case static strings, unless you’re really concerned about capacity() staying the same; the static pointer is still valid with a reduced length.