Re: [PATCH v3 1/2] rust: non_empty: add NonEmpty
From: Alexandre Courbot
Date: Thu Oct 15 2026 - 10:49:24 EST
On Thu Oct 15, 2026 at 11:02 PM JST, Gary Guo wrote:
> On Thu Oct 15, 2026 at 1:43 PM BST, Alexandre Courbot wrote:
>> On Wed Oct 14, 2026 at 11:25 PM JST, Gary Guo wrote:
>>> On Wed Oct 14, 2026 at 12:55 PM BST, Miguel Ojeda wrote:
>>>> On Wed, Oct 14, 2026 at 10:30 AM Lorenzo Delgado <lnsdev@xxxxxxxxx> wrote:
>>>>>
>>>>> +/// A container that can report whether it holds any element.
>>>>> +///
>>>>> +/// The result must not change while the container is only reachable through a shared reference.
>>>>> +///
>>>>> +/// Unsafe code may only rely on the result for a container type whose implementation it trusts,
>>>>> +/// such as the ones in this module, since a safe implementation can return anything.
>>>>> +pub trait IsEmpty {
>>>>> + /// Returns `true` if the container holds no element.
>>>>> + fn is_empty(&self) -> bool;
>>>>> +}
>>>>
>>>> Do we need this to be a safe trait? If it is unsafe, then we can
>>>> simplify the invariant and more easily think about the type, like
>>>> other `Non*`s, no?
>>>
>>> I think in this case the meaning of "empty" depends on the container itself.
>>> Unsafe code that relies on "is_empty" would be the `NonEmpty<Container>` itself,
>>> so it just needs to trust itself (as boundary of unsafe is module level).
>>>
>>> I think of almost all of the text above can be removed. The invariant of
>>> `NonEmpty` can just be "`IsEmpty::is_empty` has returned true" and how it is
>>> interpreted is up to the container type.
>>
>> Is `IsEmpty` actually useful? It needs to be implemented for every
>> container we want to wrap with essentially the same boilerplate code,
>> which looks a bit overkill to me. Couldn't we just do:
>>
>> impl<T, C: Deref<Target = [T]>> NonEmpty<C>
>
> Slice does not dereference to a slice, and arrays doesn't dereference to slices
> either.
How about `C: AsRef<[T]>` (would require an implementation for `KVec`)
or `C: Borrow<[T]>`?