Re: [PATCH 1/6] rust: alloc: add Vec::push_init

From: Gary Guo

Date: Wed Aug 19 2026 - 08:09:25 EST


On Wed Aug 19, 2026 at 12:23 PM BST, Danilo Krummrich wrote:
> On Mon Aug 17, 2026 at 2:56 PM CEST, Eliot Courtney wrote:
>> + pub fn push_init<E>(&mut self, init: impl Init<T, E>, flags: Flags) -> Result<(), E>
>> + where
>> + E: From<AllocError>,
>
> This signature rejects impl Init<T, Infallible>, which is the reason why we have
> e.g. Box::init() and Box::try_init() with different fallible signatures.
>
> So, if we follow InPlaceInit, it'd be
>
> pub fn push_init<E>(&mut self, init: impl Init<T, E>, flags: Flags) -> Result<(), Error>
> where
> Error: From<E>;
>
> and
>
> pub fn try_push_init<E>(&mut self, init: impl Init<T, E>, flags: Flags) -> Result<(), E>
> where
> E: From<AllocError>;
>
> In theory we could also simplify it to
>
> pub fn push_init(&mut self, init: impl Init<T>, flags: Flags) -> Result<(), AllocError>
>
> and
>
> pub fn try_push_init<E>(&mut self, init: impl Init<T, E>, flags: Flags) -> Result<(), E>
> where
> E: From<AllocError>,
>
> However, InPlaceInit actually achieves more with the init() and try_init()
> distinction:
>
> What init() accepts, but try_init() does not accept:
> - impl Init<T, Infallible>
> - impl Init<T, E> where Error: From<E> but NOT E: From<AllocError>
>
> What try_init() accepts, but init() does not accept:
> - impl Init<T, E> where E: From<AllocError> but NOT Error: From<E>
>
> So, with the simplification we'd technically lose out on the
>
> impl Init<T, E> where Error: From<E> but NOT E: From<AllocError>
>
> case.
>
> In any case, init() and try_init() seem a bit mixed up on their purpose
> regarding fallibility and error type strategy, but in order to really cover all
> cases I think it is necessary.

This is one of the reasons that I suggest the entry-like API. This way the
reserve and the push are separate operation and with their own failure mode.
`reserve` can only fail with `AllocError` and push can only fail with whatever
the error the initializer can fail.

The most simple case of just reserving one element:

vec.reserve_one()?.push(fallible_init)?;

the only requirement then becomes `E: From<AllocError>` and `E: From<InitError>`
where `E` is the error type in function signature, bypassing this unification
issue.

Best,
Gary