Implement these two common traits, which allow generic types to store
either an owned value or a reference to it.
The implementation leverages `as_slice` and `as_mut_slice`.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
rust/kernel/alloc/kvec.rs | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/rust/kernel/alloc/kvec.rs b/rust/kernel/alloc/kvec.rs
index 1a0dd852a468ccda6ea1b521bc1e7dbc8d7fc79c..45f813f69fe0f338a83c577752dd3ba1b3b2003f 100644
--- a/rust/kernel/alloc/kvec.rs
+++ b/rust/kernel/alloc/kvec.rs
@@ -8,6 +8,7 @@
AllocError, Allocator, Box, Flags,
};
use core::{
+ borrow::{Borrow, BorrowMut},
fmt,
marker::PhantomData,
mem::{ManuallyDrop, MaybeUninit},
@@ -890,6 +891,24 @@ fn deref_mut(&mut self) -> &mut [T] {
}
}
+impl<T, A> Borrow<[T]> for Vec<T, A>
+where
+ A: Allocator,
+{
+ fn borrow(&self) -> &[T] {
+ self.as_slice()
+ }
+}
+
+impl<T, A> BorrowMut<[T]> for Vec<T, A>
+where
+ A: Allocator,
+{
+ fn borrow_mut(&mut self) -> &mut [T] {
+ self.as_mut_slice()
+ }
+}
+
impl<T: Eq, A> Eq for Vec<T, A> where A: Allocator {}
impl<T, I: SliceIndex<[T]>, A> Index<I> for Vec<T, A>
--
2.49.0
On Sun Jun 1, 2025 at 5:00 AM CEST, Alexandre Courbot wrote: > Implement these two common traits, which allow generic types to store > either an owned value or a reference to it. I don't understand the second part of the sentence. > The implementation leverages `as_slice` and `as_mut_slice`. > > Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> > --- > rust/kernel/alloc/kvec.rs | 19 +++++++++++++++++++ > 1 file changed, 19 insertions(+) The code itself looks good. --- Cheers, Benno
Hi Benno,
On Mon Jun 2, 2025 at 1:11 AM JST, Benno Lossin wrote:
> On Sun Jun 1, 2025 at 5:00 AM CEST, Alexandre Courbot wrote:
>> Implement these two common traits, which allow generic types to store
>> either an owned value or a reference to it.
>
> I don't understand the second part of the sentence.
I want to say that Borrow allows you to do something like:
struct Foo<B: Borrow<u32>>(B);
// `foo1` owns its value...
let foo1 = Foo(0x12);
let i = 0x24;
// ... but `foo2` just borrows it, subject to the lifetime of `i`.
let foo2 = Foo(&i);
And the implementations in this series also let you do:
// `foo3`'s value is owned, but heap-allocated
let foo3 = Arc::new(KBox::new(0x56, GFP_KERNEL)?);
let j = Arc::new(0x78, GFP_KERNEL)?;
// `foo4`'s value is shared and its lifetime runtime-managed.
let foo4 = Foo(j.clone());
On Mon Jun 2, 2025 at 3:13 AM CEST, Alexandre Courbot wrote:
> Hi Benno,
>
> On Mon Jun 2, 2025 at 1:11 AM JST, Benno Lossin wrote:
>> On Sun Jun 1, 2025 at 5:00 AM CEST, Alexandre Courbot wrote:
>>> Implement these two common traits, which allow generic types to store
>>> either an owned value or a reference to it.
>>
>> I don't understand the second part of the sentence.
>
> I want to say that Borrow allows you to do something like:
>
> struct Foo<B: Borrow<u32>>(B);
>
> // `foo1` owns its value...
> let foo1 = Foo(0x12);
>
> let i = 0x24;
> // ... but `foo2` just borrows it, subject to the lifetime of `i`.
> let foo2 = Foo(&i);
>
> And the implementations in this series also let you do:
>
> // `foo3`'s value is owned, but heap-allocated
> let foo3 = Arc::new(KBox::new(0x56, GFP_KERNEL)?);
>
> let j = Arc::new(0x78, GFP_KERNEL)?;
> // `foo4`'s value is shared and its lifetime runtime-managed.
> let foo4 = Foo(j.clone());
How about something like:
Implement `Borrow<[T]>` and `BorrowMut<[T]>` for `Vec<T>`. This allows
`Vec<T>` to be used in generic APIs asking for types implementing those
traits. `[T; N]` and `&mut [T]` also implement those traits allowing
users to use either owned, borrowed and heap-owned values.
Also note this paragraph from the docs:
In particular `Eq`, `Ord` and `Hash` must be equivalent for borrowed
and owned values: `x.borrow() == y.borrow()` should give the same
result as `x == y`.
(This holds for the types that you implement it for, but I wanted to
mention it)
---
Cheers,
Benno
On Wed Jun 4, 2025 at 4:34 PM JST, Benno Lossin wrote: > On Mon Jun 2, 2025 at 3:13 AM CEST, Alexandre Courbot wrote: >> Hi Benno, >> >> On Mon Jun 2, 2025 at 1:11 AM JST, Benno Lossin wrote: >>> On Sun Jun 1, 2025 at 5:00 AM CEST, Alexandre Courbot wrote: >>>> Implement these two common traits, which allow generic types to store >>>> either an owned value or a reference to it. >>> >>> I don't understand the second part of the sentence. >> >> I want to say that Borrow allows you to do something like: >> >> struct Foo<B: Borrow<u32>>(B); >> >> // `foo1` owns its value... >> let foo1 = Foo(0x12); >> >> let i = 0x24; >> // ... but `foo2` just borrows it, subject to the lifetime of `i`. >> let foo2 = Foo(&i); >> >> And the implementations in this series also let you do: >> >> // `foo3`'s value is owned, but heap-allocated >> let foo3 = Arc::new(KBox::new(0x56, GFP_KERNEL)?); >> >> let j = Arc::new(0x78, GFP_KERNEL)?; >> // `foo4`'s value is shared and its lifetime runtime-managed. >> let foo4 = Foo(j.clone()); > > How about something like: > > Implement `Borrow<[T]>` and `BorrowMut<[T]>` for `Vec<T>`. This allows > `Vec<T>` to be used in generic APIs asking for types implementing those > traits. `[T; N]` and `&mut [T]` also implement those traits allowing > users to use either owned, borrowed and heap-owned values. This is super clear, and I think I'll just reuse this message as-is if that's ok with you. Thanks!
On Fri Jun 13, 2025 at 7:35 AM CEST, Alexandre Courbot wrote: > On Wed Jun 4, 2025 at 4:34 PM JST, Benno Lossin wrote: >> On Mon Jun 2, 2025 at 3:13 AM CEST, Alexandre Courbot wrote: >>> Hi Benno, >>> >>> On Mon Jun 2, 2025 at 1:11 AM JST, Benno Lossin wrote: >>>> On Sun Jun 1, 2025 at 5:00 AM CEST, Alexandre Courbot wrote: >>>>> Implement these two common traits, which allow generic types to store >>>>> either an owned value or a reference to it. >>>> >>>> I don't understand the second part of the sentence. >>> >>> I want to say that Borrow allows you to do something like: >>> >>> struct Foo<B: Borrow<u32>>(B); >>> >>> // `foo1` owns its value... >>> let foo1 = Foo(0x12); >>> >>> let i = 0x24; >>> // ... but `foo2` just borrows it, subject to the lifetime of `i`. >>> let foo2 = Foo(&i); >>> >>> And the implementations in this series also let you do: >>> >>> // `foo3`'s value is owned, but heap-allocated >>> let foo3 = Arc::new(KBox::new(0x56, GFP_KERNEL)?); >>> >>> let j = Arc::new(0x78, GFP_KERNEL)?; >>> // `foo4`'s value is shared and its lifetime runtime-managed. >>> let foo4 = Foo(j.clone()); >> >> How about something like: >> >> Implement `Borrow<[T]>` and `BorrowMut<[T]>` for `Vec<T>`. This allows >> `Vec<T>` to be used in generic APIs asking for types implementing those >> traits. `[T; N]` and `&mut [T]` also implement those traits allowing >> users to use either owned, borrowed and heap-owned values. > > This is super clear, and I think I'll just reuse this message as-is if > that's ok with you. Thanks! Sure! --- Cheers, Benno
On Mon, Jun 02, 2025 at 10:13:22AM +0900, Alexandre Courbot wrote: > Hi Benno, > > On Mon Jun 2, 2025 at 1:11 AM JST, Benno Lossin wrote: > > On Sun Jun 1, 2025 at 5:00 AM CEST, Alexandre Courbot wrote: > >> Implement these two common traits, which allow generic types to store > >> either an owned value or a reference to it. > > > > I don't understand the second part of the sentence. > > I want to say that Borrow allows you to do something like: > > struct Foo<B: Borrow<u32>>(B); > > // `foo1` owns its value... > let foo1 = Foo(0x12); > > let i = 0x24; > // ... but `foo2` just borrows it, subject to the lifetime of `i`. > let foo2 = Foo(&i); > > And the implementations in this series also let you do: > > // `foo3`'s value is owned, but heap-allocated > let foo3 = Arc::new(KBox::new(0x56, GFP_KERNEL)?); > > let j = Arc::new(0x78, GFP_KERNEL)?; > // `foo4`'s value is shared and its lifetime runtime-managed. > let foo4 = Foo(j.clone()); Maybe you could put these in the "# Examples" section before impl blocks. E.g /// # Examples /// ``` /// <you case above> /// ``` impl<T, A> Borrow<[T]> for Vec<T, A> ... Regards, Boqun
On Tue Jun 3, 2025 at 12:06 AM JST, Boqun Feng wrote: > On Mon, Jun 02, 2025 at 10:13:22AM +0900, Alexandre Courbot wrote: >> Hi Benno, >> >> On Mon Jun 2, 2025 at 1:11 AM JST, Benno Lossin wrote: >> > On Sun Jun 1, 2025 at 5:00 AM CEST, Alexandre Courbot wrote: >> >> Implement these two common traits, which allow generic types to store >> >> either an owned value or a reference to it. >> > >> > I don't understand the second part of the sentence. >> >> I want to say that Borrow allows you to do something like: >> >> struct Foo<B: Borrow<u32>>(B); >> >> // `foo1` owns its value... >> let foo1 = Foo(0x12); >> >> let i = 0x24; >> // ... but `foo2` just borrows it, subject to the lifetime of `i`. >> let foo2 = Foo(&i); >> >> And the implementations in this series also let you do: >> >> // `foo3`'s value is owned, but heap-allocated >> let foo3 = Arc::new(KBox::new(0x56, GFP_KERNEL)?); >> >> let j = Arc::new(0x78, GFP_KERNEL)?; >> // `foo4`'s value is shared and its lifetime runtime-managed. >> let foo4 = Foo(j.clone()); > > Maybe you could put these in the "# Examples" section before impl > blocks. E.g > > /// # Examples > /// ``` > /// <you case above> > /// ``` > impl<T, A> Borrow<[T]> for Vec<T, A> ... I've started doing this, but it felt like I was writing down the obvious as this kind of use is precisely what Borrow is intended for. I think Benno's suggestion for the commit log addresses your request for clarification, but let me add these on v2 anyway - we can always remove them if we conclude they are unnecessary.
On Mon Jun 2, 2025 at 5:06 PM CEST, Boqun Feng wrote: > On Mon, Jun 02, 2025 at 10:13:22AM +0900, Alexandre Courbot wrote: >> On Mon Jun 2, 2025 at 1:11 AM JST, Benno Lossin wrote: >> > On Sun Jun 1, 2025 at 5:00 AM CEST, Alexandre Courbot wrote: >> >> Implement these two common traits, which allow generic types to store >> >> either an owned value or a reference to it. >> > >> > I don't understand the second part of the sentence. >> >> I want to say that Borrow allows you to do something like: >> >> struct Foo<B: Borrow<u32>>(B); >> >> // `foo1` owns its value... >> let foo1 = Foo(0x12); >> >> let i = 0x24; >> // ... but `foo2` just borrows it, subject to the lifetime of `i`. >> let foo2 = Foo(&i); >> >> And the implementations in this series also let you do: >> >> // `foo3`'s value is owned, but heap-allocated >> let foo3 = Arc::new(KBox::new(0x56, GFP_KERNEL)?); >> >> let j = Arc::new(0x78, GFP_KERNEL)?; >> // `foo4`'s value is shared and its lifetime runtime-managed. >> let foo4 = Foo(j.clone()); > > Maybe you could put these in the "# Examples" section before impl > blocks. E.g > > /// # Examples > /// ``` > /// <you case above> > /// ``` > impl<T, A> Borrow<[T]> for Vec<T, A> ... Does that get rendered in the docs? If not, I don't think we should do it. --- Cheers, Benno
On Mon, Jun 02, 2025 at 10:21:12PM +0200, Benno Lossin wrote: > On Mon Jun 2, 2025 at 5:06 PM CEST, Boqun Feng wrote: > > On Mon, Jun 02, 2025 at 10:13:22AM +0900, Alexandre Courbot wrote: > >> On Mon Jun 2, 2025 at 1:11 AM JST, Benno Lossin wrote: > >> > On Sun Jun 1, 2025 at 5:00 AM CEST, Alexandre Courbot wrote: > >> >> Implement these two common traits, which allow generic types to store > >> >> either an owned value or a reference to it. > >> > > >> > I don't understand the second part of the sentence. > >> > >> I want to say that Borrow allows you to do something like: > >> > >> struct Foo<B: Borrow<u32>>(B); > >> > >> // `foo1` owns its value... > >> let foo1 = Foo(0x12); > >> > >> let i = 0x24; > >> // ... but `foo2` just borrows it, subject to the lifetime of `i`. > >> let foo2 = Foo(&i); > >> > >> And the implementations in this series also let you do: > >> > >> // `foo3`'s value is owned, but heap-allocated > >> let foo3 = Arc::new(KBox::new(0x56, GFP_KERNEL)?); > >> > >> let j = Arc::new(0x78, GFP_KERNEL)?; > >> // `foo4`'s value is shared and its lifetime runtime-managed. > >> let foo4 = Foo(j.clone()); > > > > Maybe you could put these in the "# Examples" section before impl > > blocks. E.g > > > > /// # Examples > > /// ``` > > /// <you case above> > > /// ``` > > impl<T, A> Borrow<[T]> for Vec<T, A> ... > > Does that get rendered in the docs? If not, I don't think we should do > it. It does. I just tried myself, in the "Trait Implementations" section, if you provide a doc comment for an impl block, it will show under the "impl line" of corresponding to that impl block, including ```code```. Regards, Boqun > > --- > Cheers, > Benno
© 2016 - 2026 Red Hat, Inc.