[PATCH 5/7] gpu: nova-core: add extra conversion functions and traits

Alexandre Courbot posted 7 patches 3 months, 2 weeks ago
There is a newer version of this series
[PATCH 5/7] gpu: nova-core: add extra conversion functions and traits
Posted by Alexandre Courbot 3 months, 2 weeks ago
The core library's `From` implementations do not cover conversions
that are not portable or future-proof. For instance, even though it is
safe today, `From<usize>` is not implemented for `u64` because of the
possibility to support larger-than-64bit architectures in the future.

However, the kernel supports a narrower set of architectures, and in the
case of Nova we only support 64-bit. This makes it helpful and desirable
to provide more infallible conversions, lest we need to rely on the `as`
keyword and carry the risk of silently losing data.

Thus, introduce a new module `num` that provides safe const functions
performing more conversions allowed by the build target, as well as
`FromAs` and `IntoAs` traits that are just extensions of `From` and
`Into` to conversions that are known to be lossless.

Suggested-by: Danilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/rust-for-linux/DDK4KADWJHMG.1FUPL3SDR26XF@kernel.org/
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
 drivers/gpu/nova-core/nova_core.rs |   1 +
 drivers/gpu/nova-core/num.rs       | 159 +++++++++++++++++++++++++++++++++++++
 2 files changed, 160 insertions(+)

diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index e130166c1086..9180ec9c27ef 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -13,6 +13,7 @@
 mod gfw;
 mod gpu;
 mod gsp;
+mod num;
 mod regs;
 mod vbios;
 
diff --git a/drivers/gpu/nova-core/num.rs b/drivers/gpu/nova-core/num.rs
new file mode 100644
index 000000000000..6b9d4e89dbf5
--- /dev/null
+++ b/drivers/gpu/nova-core/num.rs
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Numerical helpers functions and traits.
+//!
+//! This is essentially a staging module for code to mature until it can be moved to the `kernel`
+//! crate.
+
+/// Infallibly converts a `usize` to `u64`.
+///
+/// This conversion is always lossless as Linux only supports 32-bit and 64-bit platforms, thus a
+/// `usize` is always smaller than or of the same size as a `u64`.
+///
+/// Prefer this over the `as` keyword to ensure no lossy conversions are performed.
+///
+/// This is for use from a `const` context. For non `const` use, prefer the [`FromAs`] and
+/// [`IntoAs`] traits.
+pub(crate) const fn usize_as_u64(value: usize) -> u64 {
+    kernel::static_assert!(size_of::<u64>() >= size_of::<usize>());
+
+    value as u64
+}
+
+#[cfg(CONFIG_32BIT)]
+/// Infallibly converts a `usize` to `u32` on 32-bit platforms.
+///
+/// This conversion is always lossless on 32-bit platforms, where a `usize` is the same size as a
+/// `u32`.
+///
+/// Prefer this over the `as` keyword to ensure no lossy conversions are performed.
+///
+/// This is for use from a `const` context. For non `const` use, prefer the [`FromAs`] and
+/// [`IntoAs`] traits.
+pub(crate) const fn usize_as_u32(value: usize) -> u32 {
+    kernel::static_assert!(size_of::<u32>() >= size_of::<usize>());
+
+    value as u32
+}
+
+/// Infallibly converts a `u32` to `usize`.
+///
+/// This conversion is always lossless as Linux only supports 32-bit and 64-bit platforms, thus a
+/// `u32` is always smaller than or of the same size as a `usize`.
+///
+/// Prefer this over the `as` keyword to ensure no lossy conversions are performed.
+///
+/// This is for use from a `const` context. For non `const` use, prefer the [`FromAs`] and
+/// [`IntoAs`] traits.
+pub(crate) const fn u32_as_usize(value: u32) -> usize {
+    kernel::static_assert!(size_of::<usize>() >= size_of::<u32>());
+
+    value as usize
+}
+
+#[cfg(CONFIG_64BIT)]
+/// Infallibly converts a `u64` to `usize` on 64-bit platforms.
+///
+/// This conversion is always lossless on 64-bit platforms, where a `usize` is the same size as a
+/// `u64`.
+///
+/// Prefer this over the `as` keyword to ensure no lossy conversions are performed.
+///
+/// This is for use from a `const` context. For non `const` use, prefer the [`FromAs`] and
+/// [`IntoAs`] traits.
+pub(crate) const fn u64_as_usize(value: u64) -> usize {
+    kernel::static_assert!(size_of::<usize>() >= size_of::<u64>());
+
+    value as usize
+}
+
+/// Extension trait providing guaranteed lossless conversion to `Self` from `T`.
+///
+/// The standard library's `From` implementations do not cover conversions that are not portable or
+/// future-proof. For instance, even though it is safe today, `From<usize>` is not implemented for
+/// `u64` because of the possibility to support larger-than-64bit architectures in the future.
+///
+/// The workaround is to either deal with the error handling of `TryFrom` for an operation that
+/// technically cannot fail, or to use the `as` keyword, which can silently strip data if the
+/// destination type is smaller than the source.
+///
+/// Both options are hardly acceptable for the kernel. It is also a much more architecture
+/// dependent environment, supporting only 32 and 64 bit architectures, with some modules
+/// explicitly depending on a specific bus witdth that could greatly benefit from infallible
+/// conversion operations.
+///
+/// Thus this extension trait that provides, for the architecture the kernel is built for, safe
+/// conversion between types for which such conversion is lossless.
+///
+/// In other words, this trait is implemented if, for the current build target and with `t: T`, the
+/// `t as Self` operation is completely lossless.
+///
+/// Prefer this over the `as` keyword to ensure no lossy conversions are performed.
+///
+/// If you need to perform a conversion in `const` context, use [`u64_as_usize`],
+/// [`u32_as_usize`], [`usize_as_u64`], or [`usize_as_u32`].
+///
+/// # Examples
+///
+/// ```
+/// use crate::num::FromAs;
+///
+/// assert_eq!(usize::from_as(0xf00u32), 0xf00u32 as usize);
+/// ```
+pub(crate) trait FromAs<T> {
+    /// Create a `Self` from `value`. This operation is guaranteed to be lossless.
+    fn from_as(value: T) -> Self;
+}
+
+impl FromAs<usize> for u64 {
+    fn from_as(value: usize) -> Self {
+        usize_as_u64(value)
+    }
+}
+
+#[cfg(CONFIG_32BIT)]
+impl FromAs<usize> for u32 {
+    fn from_as(value: usize) -> Self {
+        usize_as_u32(value)
+    }
+}
+
+impl FromAs<u32> for usize {
+    fn from_as(value: u32) -> Self {
+        u32_as_usize(value)
+    }
+}
+
+#[cfg(CONFIG_64BIT)]
+impl FromAs<u64> for usize {
+    fn from_as(value: u64) -> Self {
+        u64_as_usize(value)
+    }
+}
+
+/// Counterpart to the [`FromAs`] trait, i.e. this trait is to [`FromAs`] what [`Into`] is to
+/// [`From`].
+///
+/// See the documentation of [`FromAs`] for the motivation.
+///
+/// # Examples
+///
+/// ```
+/// use crate::num::IntoAs;
+///
+/// assert_eq!(0xf00u32.into_as(), 0xf00u32 as usize);
+/// ```
+pub(crate) trait IntoAs<T> {
+    /// Convert `self` into a `T`. This operation is guaranteed to be lossless.
+    fn into_as(self) -> T;
+}
+
+/// Reverse operation for types implementing [`FromAs`].
+impl<S, T> IntoAs<T> for S
+where
+    T: FromAs<S>,
+{
+    fn into_as(self) -> T {
+        T::from_as(self)
+    }
+}

-- 
2.51.0
Re: [PATCH 5/7] gpu: nova-core: add extra conversion functions and traits
Posted by Miguel Ojeda 3 months, 2 weeks ago
On Sun, Oct 26, 2025 at 3:40 PM Alexandre Courbot <acourbot@nvidia.com> wrote:
>
> +/// Infallibly converts a `usize` to `u64`.
> +///
> +/// This conversion is always lossless as Linux only supports 32-bit and 64-bit platforms, thus a
> +/// `usize` is always smaller than or of the same size as a `u64`.
> +///
> +/// Prefer this over the `as` keyword to ensure no lossy conversions are performed.
> +///
> +/// This is for use from a `const` context. For non `const` use, prefer the [`FromAs`] and
> +/// [`IntoAs`] traits.
> +pub(crate) const fn usize_as_u64(value: usize) -> u64 {
> +    kernel::static_assert!(size_of::<u64>() >= size_of::<usize>());
> +
> +    value as u64
> +}

Since you have the static asserts, this is fine today.

However, we may actually get 128-bit architectures in the
not-so-distant future -- Matthew suggests to be ready by 2035:

    https://lwn.net/Articles/908026/

So this one in particular may actually not be true "soon" -- we also
had related discussions about these assumptions, e.g.:

    https://lore.kernel.org/rust-for-linux/CANiq72m9AeqFKHrRniQ5Nr9vPv2MmUMHFTuuj5ydmqo+OYn60A@mail.gmail.com/

So we should consider having the `cfg` already to prevent people from
assuming it will be always available, and likely a note in its docs,
i.e. we may introducing trouble to port later on to new architectures.
Similarly, the docs of the trait may need rewording.

What do you think?

Regarding the `.into_as()` name, it makes sense, but it can be a bit
surprising when reading out of context... The standalone functions are
super clear, in comparison. But I am not sure what could be better.
`into_in_this_arch()` or similar could emphasize that this will only
work in certain architectures, i.e. it is "an `into()` for this arch"
rather than the general one.
That would go well with the idea that you didn't implement it for
other obvious types, which I guess was to avoid developers using this
instead of `into()` by mistake, right?

(By the way, please use intra-doc links on the primitives too.)

Thanks!

Cheers,
Miguel
Re: [PATCH 5/7] gpu: nova-core: add extra conversion functions and traits
Posted by John Hubbard 3 months, 2 weeks ago
On 10/26/25 9:44 AM, Miguel Ojeda wrote:
> On Sun, Oct 26, 2025 at 3:40 PM Alexandre Courbot <acourbot@nvidia.com> wrote:
...

> Regarding the `.into_as()` name, it makes sense, but it can be a bit
> surprising when reading out of context... The standalone functions are
> super clear, in comparison. But I am not sure what could be better.
> `into_in_this_arch()` or similar could emphasize that this will only
> work in certain architectures, i.e. it is "an `into()` for this arch"
> rather than the general one.
> That would go well with the idea that you didn't implement it for
> other obvious types, which I guess was to avoid developers using this
> instead of `into()` by mistake, right?
> 

Exactly: the into-as, from-as naming suffers from *appearing* to be
familiar and readable, but actually, the naming gives no hint as to 
what it is really doing--nor how it is subtly different from the
basic from/as/into standard conversions.

Instead, we need to add something (almost anything) to the name, to
make it clearly different from the from/as/into.

into_for_arch() goes in that direction, for example.

thanks,
-- 
John Hubbard

Re: [PATCH 5/7] gpu: nova-core: add extra conversion functions and traits
Posted by Alexandre Courbot 3 months, 1 week ago
On Tue Oct 28, 2025 at 3:46 AM JST, John Hubbard wrote:
> On 10/26/25 9:44 AM, Miguel Ojeda wrote:
>> On Sun, Oct 26, 2025 at 3:40 PM Alexandre Courbot <acourbot@nvidia.com> wrote:
> ...
>
>> Regarding the `.into_as()` name, it makes sense, but it can be a bit
>> surprising when reading out of context... The standalone functions are
>> super clear, in comparison. But I am not sure what could be better.
>> `into_in_this_arch()` or similar could emphasize that this will only
>> work in certain architectures, i.e. it is "an `into()` for this arch"
>> rather than the general one.
>> That would go well with the idea that you didn't implement it for
>> other obvious types, which I guess was to avoid developers using this
>> instead of `into()` by mistake, right?
>> 
>
> Exactly: the into-as, from-as naming suffers from *appearing* to be
> familiar and readable, but actually, the naming gives no hint as to 
> what it is really doing--nor how it is subtly different from the
> basic from/as/into standard conversions.
>
> Instead, we need to add something (almost anything) to the name, to
> make it clearly different from the from/as/into.
>
> into_for_arch() goes in that direction, for example.

I'd like to get more input on that, for I am not sure how we can stay
succint in the naming, while carrying the relevant information.
`into_arch` does not sound much more explanatory than `into_as` - the
intent with the latter was to say "I would normally have done an `as`,
but instead here is a method that attests that this operations is indeed
lossless and safe".

The best naming scheme I could think of is to have the methods carry the
source or destination types: e.g. `from_usize` or `into_usize` (like the
standalone functions), but that would require defining as many traits,
and increase the number of imports - if we go that way, we might just as
well drop the traits completely and use the standalone functions.

`into_native` also comes to mind, but like `arch`, it can mean many
things depending on the context.

... I think I still believe that `into_as` is the clearest name, once
one has read the documentation for the trait - which one should be
expected to do anyway. :)
Re: [PATCH 5/7] gpu: nova-core: add extra conversion functions and traits
Posted by John Hubbard 3 months, 1 week ago
On 10/28/25 7:44 AM, Alexandre Courbot wrote:
> On Tue Oct 28, 2025 at 3:46 AM JST, John Hubbard wrote:
>> On 10/26/25 9:44 AM, Miguel Ojeda wrote:
>>> On Sun, Oct 26, 2025 at 3:40 PM Alexandre Courbot <acourbot@nvidia.com> wrote:
>> ...
>>
>>> Regarding the `.into_as()` name, it makes sense, but it can be a bit
>>> surprising when reading out of context... The standalone functions are
>>> super clear, in comparison. But I am not sure what could be better.
>>> `into_in_this_arch()` or similar could emphasize that this will only
>>> work in certain architectures, i.e. it is "an `into()` for this arch"
>>> rather than the general one.
>>> That would go well with the idea that you didn't implement it for
>>> other obvious types, which I guess was to avoid developers using this
>>> instead of `into()` by mistake, right?
>>>
>>
>> Exactly: the into-as, from-as naming suffers from *appearing* to be
>> familiar and readable, but actually, the naming gives no hint as to
>> what it is really doing--nor how it is subtly different from the
>> basic from/as/into standard conversions.
>>
>> Instead, we need to add something (almost anything) to the name, to
>> make it clearly different from the from/as/into.
>>
>> into_for_arch() goes in that direction, for example.
> 
> I'd like to get more input on that, for I am not sure how we can stay
> succint in the naming, while carrying the relevant information.

That's too many constraints: if you want an extremely short name
that carries information, *and* avoids (as requested here) confusion
with existing "as" methods, then...you can't.

But you are allowed to be less succinct here, because the more
specialized and rare a case is, the longer you can make the name.
And here, you are definitely allowed a few more characters.


> `into_arch` does not sound much more explanatory than `into_as` - the
> intent with the latter was to say "I would normally have done an `as`,
> but instead here is a method that attests that this operations is indeed
> lossless and safe".
> 
> The best naming scheme I could think of is to have the methods carry the
> source or destination types: e.g. `from_usize` or `into_usize` (like the
> standalone functions), but that would require defining as many traits,
> and increase the number of imports - if we go that way, we might just as
> well drop the traits completely and use the standalone functions.

Accurate names are really desirable; maybe we shouldn't completely
close the door to the above approach.

thanks,
John Hubbard

> 
> `into_native` also comes to mind, but like `arch`, it can mean many
> things depending on the context.
> 
> ... I think I still believe that `into_as` is the clearest name, once
> one has read the documentation for the trait - which one should be
> expected to do anyway. :)

Re: [PATCH 5/7] gpu: nova-core: add extra conversion functions and traits
Posted by Alexandre Courbot 3 months, 1 week ago
On Wed Oct 29, 2025 at 2:18 AM JST, John Hubbard wrote:
> On 10/28/25 7:44 AM, Alexandre Courbot wrote:
>> On Tue Oct 28, 2025 at 3:46 AM JST, John Hubbard wrote:
>>> On 10/26/25 9:44 AM, Miguel Ojeda wrote:
>>>> On Sun, Oct 26, 2025 at 3:40 PM Alexandre Courbot <acourbot@nvidia.com> wrote:
>>> ...
>>>
>>>> Regarding the `.into_as()` name, it makes sense, but it can be a bit
>>>> surprising when reading out of context... The standalone functions are
>>>> super clear, in comparison. But I am not sure what could be better.
>>>> `into_in_this_arch()` or similar could emphasize that this will only
>>>> work in certain architectures, i.e. it is "an `into()` for this arch"
>>>> rather than the general one.
>>>> That would go well with the idea that you didn't implement it for
>>>> other obvious types, which I guess was to avoid developers using this
>>>> instead of `into()` by mistake, right?
>>>>
>>>
>>> Exactly: the into-as, from-as naming suffers from *appearing* to be
>>> familiar and readable, but actually, the naming gives no hint as to
>>> what it is really doing--nor how it is subtly different from the
>>> basic from/as/into standard conversions.
>>>
>>> Instead, we need to add something (almost anything) to the name, to
>>> make it clearly different from the from/as/into.
>>>
>>> into_for_arch() goes in that direction, for example.
>> 
>> I'd like to get more input on that, for I am not sure how we can stay
>> succint in the naming, while carrying the relevant information.
>
> That's too many constraints: if you want an extremely short name
> that carries information, *and* avoids (as requested here) confusion
> with existing "as" methods, then...you can't.
>
> But you are allowed to be less succinct here, because the more
> specialized and rare a case is, the longer you can make the name.
> And here, you are definitely allowed a few more characters.
>
>
>> `into_arch` does not sound much more explanatory than `into_as` - the
>> intent with the latter was to say "I would normally have done an `as`,
>> but instead here is a method that attests that this operations is indeed
>> lossless and safe".
>> 
>> The best naming scheme I could think of is to have the methods carry the
>> source or destination types: e.g. `from_usize` or `into_usize` (like the
>> standalone functions), but that would require defining as many traits,
>> and increase the number of imports - if we go that way, we might just as
>> well drop the traits completely and use the standalone functions.
>
> Accurate names are really desirable; maybe we shouldn't completely
> close the door to the above approach.

I think we have reached the stage where any responsible adult would
shove this whole discussion into a LLM and see what it comes up with.

And the candidate is... `FromSafeCast`/`IntoSafeCast`. Which I have to
say sounds like a good middle ground? :) The intent is definitely to
perform a safe cast here.
Re: [PATCH 5/7] gpu: nova-core: add extra conversion functions and traits
Posted by John Hubbard 3 months, 1 week ago
On 10/28/25 3:32 PM, Alexandre Courbot wrote:
> On Wed Oct 29, 2025 at 2:18 AM JST, John Hubbard wrote:
>> On 10/28/25 7:44 AM, Alexandre Courbot wrote:
>>> On Tue Oct 28, 2025 at 3:46 AM JST, John Hubbard wrote:
>>>> On 10/26/25 9:44 AM, Miguel Ojeda wrote:
>>>>> On Sun, Oct 26, 2025 at 3:40 PM Alexandre Courbot <acourbot@nvidia.com> wrote:
>>>> ...
...
> I think we have reached the stage where any responsible adult would
> shove this whole discussion into a LLM and see what it comes up with.
> 
> And the candidate is... `FromSafeCast`/`IntoSafeCast`. Which I have to
> say sounds like a good middle ground? :) The intent is definitely to
> perform a safe cast here.

Ship it! :)

thanks,
-- 
John Hubbard

Re: [PATCH 5/7] gpu: nova-core: add extra conversion functions and traits
Posted by Miguel Ojeda 3 months, 1 week ago
On Tue, Oct 28, 2025 at 3:44 PM Alexandre Courbot <acourbot@nvidia.com> wrote:
>
> intent with the latter was to say "I would normally have done an `as`,
> but instead here is a method that attests that this operations is indeed
> lossless and safe".

Yeah, so you want that, when we see `_as`, we are reminded that this
is the equivalent but lossless of that, which sounds OK. Though I
wouldn't say "I would normally have done ...", but rather turn it
around and say "Since we want to avoid `as`, here is a method ...".

Now, I suggested a change because typically I would expect names to
mention what they are about/do, rather than how they are implemented.
The implementation in this case also doesn't say much, i.e. a type
cast expression can be used for many things, and worse, the operator
may or may not be lossless, so it isn't a big hint.

But, yeah, I understand that you want to evoke the relationship above.

I also suggested it because when I wrote the message I was thinking
about the `cfg`s message, i.e. most of these depend on the
architecture, and thus having an `arch` or similar does evoke a
"careful, my code may not be portable anymore".

On the other hand, it is true that the `u32_as_usize` case will most
likely always be available, in practice, unlike the others. So an
`arch` for that one isn't great (but I guess it could still matter for
someone wanting to reuse the code in a different project/domain).

In any case, personally I don't mind it too much either way --
whatever looks best for most.

Cheers,
Miguel
Re: [PATCH 5/7] gpu: nova-core: add extra conversion functions and traits
Posted by Joel Fernandes 3 months, 2 weeks ago

On 10/27/2025 2:46 PM, John Hubbard wrote:
> On 10/26/25 9:44 AM, Miguel Ojeda wrote:
>> On Sun, Oct 26, 2025 at 3:40 PM Alexandre Courbot <acourbot@nvidia.com> wrote:
> ...
> 
>> Regarding the `.into_as()` name, it makes sense, but it can be a bit
>> surprising when reading out of context... The standalone functions are
>> super clear, in comparison. But I am not sure what could be better.
>> `into_in_this_arch()` or similar could emphasize that this will only
>> work in certain architectures, i.e. it is "an `into()` for this arch"
>> rather than the general one.
>> That would go well with the idea that you didn't implement it for
>> other obvious types, which I guess was to avoid developers using this
>> instead of `into()` by mistake, right?
>>
> 
> Exactly: the into-as, from-as naming suffers from *appearing* to be
> familiar and readable, but actually, the naming gives no hint as to 
> what it is really doing--nor how it is subtly different from the
> basic from/as/into standard conversions.
> 
> Instead, we need to add something (almost anything) to the name, to
> make it clearly different from the from/as/into.
> 
> into_for_arch() goes in that direction, for example.

100% agree with John. Thanks,

 - Joel

Re: [PATCH 5/7] gpu: nova-core: add extra conversion functions and traits
Posted by Alexandre Courbot 3 months, 2 weeks ago
On Mon Oct 27, 2025 at 1:44 AM JST, Miguel Ojeda wrote:
> On Sun, Oct 26, 2025 at 3:40 PM Alexandre Courbot <acourbot@nvidia.com> wrote:
>>
>> +/// Infallibly converts a `usize` to `u64`.
>> +///
>> +/// This conversion is always lossless as Linux only supports 32-bit and 64-bit platforms, thus a
>> +/// `usize` is always smaller than or of the same size as a `u64`.
>> +///
>> +/// Prefer this over the `as` keyword to ensure no lossy conversions are performed.
>> +///
>> +/// This is for use from a `const` context. For non `const` use, prefer the [`FromAs`] and
>> +/// [`IntoAs`] traits.
>> +pub(crate) const fn usize_as_u64(value: usize) -> u64 {
>> +    kernel::static_assert!(size_of::<u64>() >= size_of::<usize>());
>> +
>> +    value as u64
>> +}
>
> Since you have the static asserts, this is fine today.
>
> However, we may actually get 128-bit architectures in the
> not-so-distant future -- Matthew suggests to be ready by 2035:
>
>     https://lwn.net/Articles/908026/
>
> So this one in particular may actually not be true "soon" -- we also
> had related discussions about these assumptions, e.g.:
>
>     https://lore.kernel.org/rust-for-linux/CANiq72m9AeqFKHrRniQ5Nr9vPv2MmUMHFTuuj5ydmqo+OYn60A@mail.gmail.com/
>
> So we should consider having the `cfg` already to prevent people from
> assuming it will be always available, and likely a note in its docs,
> i.e. we may introducing trouble to port later on to new architectures.
> Similarly, the docs of the trait may need rewording.
>
> What do you think?

Do you mean adding a `#[cfg(any(CONFIG_32BIT, CONFIG_64BIT))]`? That
sounds like a good idea.

The static asserts will break whenever one of these functions needs to
be protected by more conditional compilation anyway, but for consistency
I agree it would make sense to add it now.

>
> Regarding the `.into_as()` name, it makes sense, but it can be a bit
> surprising when reading out of context... The standalone functions are
> super clear, in comparison. But I am not sure what could be better.
> `into_in_this_arch()` or similar could emphasize that this will only
> work in certain architectures, i.e. it is "an `into()` for this arch"
> rather than the general one.
> That would go well with the idea that you didn't implement it for
> other obvious types, which I guess was to avoid developers using this
> instead of `into()` by mistake, right?

Exactly, the trait implementation is limited to conversions not already
covered by `From` (because if there is a `From` implementation, it is
obviously the preferred way to do it).

The const functions, by contrast, need to cover all safe conversions as
we cannot use `From` in a const context yet.

I am happy to take suggestions for naming (I also think the current name
is not great) - we could also consider dropping the trait altogether,
but I find it more convenient for non-const contexts.

>
> (By the way, please use intra-doc links on the primitives too.)

Thanks, it never occured to me that we could. ^_^;
Re: [PATCH 5/7] gpu: nova-core: add extra conversion functions and traits
Posted by Danilo Krummrich 3 months, 2 weeks ago
On 10/26/25 3:39 PM, Alexandre Courbot wrote:
> +#[cfg(CONFIG_32BIT)]
> +/// Infallibly converts a `usize` to `u32` on 32-bit platforms.
> +///
> +/// This conversion is always lossless on 32-bit platforms, where a `usize` is the same size as a
> +/// `u32`.
> +///
> +/// Prefer this over the `as` keyword to ensure no lossy conversions are performed.
> +///
> +/// This is for use from a `const` context. For non `const` use, prefer the [`FromAs`] and
> +/// [`IntoAs`] traits.
> +pub(crate) const fn usize_as_u32(value: usize) -> u32 {
> +    kernel::static_assert!(size_of::<u32>() >= size_of::<usize>());
> +
> +    value as u32
> +}

Given that nova-core depends on CONFIG_64BIT, I assume you added this predicting
that we'll move this to the kernel crate.

For core code (and maybe other drivers) I think we also want the same thing for
signed types, but I think it's also fine to add them when moving things into the
kernel crate.
Re: [PATCH 5/7] gpu: nova-core: add extra conversion functions and traits
Posted by Alexandre Courbot 3 months, 2 weeks ago
On Mon Oct 27, 2025 at 12:40 AM JST, Danilo Krummrich wrote:
> On 10/26/25 3:39 PM, Alexandre Courbot wrote:
>> +#[cfg(CONFIG_32BIT)]
>> +/// Infallibly converts a `usize` to `u32` on 32-bit platforms.
>> +///
>> +/// This conversion is always lossless on 32-bit platforms, where a `usize` is the same size as a
>> +/// `u32`.
>> +///
>> +/// Prefer this over the `as` keyword to ensure no lossy conversions are performed.
>> +///
>> +/// This is for use from a `const` context. For non `const` use, prefer the [`FromAs`] and
>> +/// [`IntoAs`] traits.
>> +pub(crate) const fn usize_as_u32(value: usize) -> u32 {
>> +    kernel::static_assert!(size_of::<u32>() >= size_of::<usize>());
>> +
>> +    value as u32
>> +}
>
> Given that nova-core depends on CONFIG_64BIT, I assume you added this predicting
> that we'll move this to the kernel crate.

That's correct.

>
> For core code (and maybe other drivers) I think we also want the same thing for
> signed types, but I think it's also fine to add them when moving things into the
> kernel crate.

We'll definitely want this. Nova-core does not use require signed types,
which is why I omitted them for now - and also so save some labor as we
are still discussing the fitness of this design.