Sometimes it is useful to create a string from a string literal but also want to make sure that there is extra space for future additions. It is currently possible to do the following:
let mut s = String::reserve(56);
s.push_str("foobar");
However I think it would be clearer in most cases to have something like the following:
let s = String::from_reserve("foobar", 50);
These two behave the same (modulo non-exact allocations). But I would argue that the second is clear in its intent. Plus since it is reserving space in addition (since that is how the reserve method works), you don't need to manually calculate the difference (like in the first case).
Unresolved Questions:
What should this function be called?
from_reserve
from_and_reserve
Should we have an exact counterpoint as well?
Does this need to be an RFC or could I just submit a PR for an unstable associated functions?
For whether this would be a PR or and RFC, I'd say it depends on whether you'd expect it to be a pattern. Is this String-specific somehow? Should it also apply to Vec? What about other containers? The more it's a one-off the more it should just be a PR; the more it's a convention that would imply that crates should offer it on their own types the more is should be a full RFC.
For example, if this exists, does it imply that there should also be .collect_reserve(10)?
(And of course there's always the usual question of whether this needs to be more than just a helper in your code somewhere, since it's trivial to write in terms of existing things.)
So I potential problem I see with a method like .collect_reserve(10) is that the benefit of this API would be to do everything in one allocation. And unless you are dealing with ExactSizeIterator (or something similar) that is not possible in general.
And furthermore Iterator<T> doesn't even have a .collect_into(&mut vec) so that seems like a better API to have before considering a .collect_reserve(...).
Not the iterator but the Extend into which to collect. iter.collect_into(Vec::with_capacity(123)) is one use case, collecting several iterators into one Vec is another.
The latter allowing (... long chain of iterator methods...).collect_onto(Vec::with_capacity(100)), but not working well for a container not available as owned.
Sadly there's no blanket impl of Extend for &mut impl Extend (and it's a breaking change to add one) so they can't both be done with the same signature.
The original RFC issue proposed to use BorrowMut to support both, but it introduced inference problems due to the double generic parameters and so that idea was abandoned.
AsMut<T> is not automatically implemented for T, so it can't support both.