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

Reply via email to