public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Charalampos Mitrodimas <charmitro@posteo.net>
To: "Alexandre Courbot" <acourbot@nvidia.com>
Cc: "Jesung Yang" <y.j3ms.n@gmail.com>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <lossin@kernel.org>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Danilo Krummrich" <dakr@kernel.org>,
	linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
	nouveau@lists.freedesktop.org
Subject: Re: [PATCH v5 2/4] rust: macros: add derive macro for `TryFrom`
Date: Tue, 17 Feb 2026 02:45:16 +0000	[thread overview]
Message-ID: <874ingf5qe.fsf@posteo.net> (raw)
In-Reply-To: <DGGV2METTDXF.1BCNNP5T0TPV3@nvidia.com>

"Alexandre Courbot" <acourbot@nvidia.com> writes:

> On Fri Feb 6, 2026 at 6:06 AM JST, Jesung Yang wrote:
>> On Wed Feb 4, 2026 at 10:39 AM KST, Charalampos Mitrodimas wrote:
>>> Jesung Yang via B4 Relay <devnull+y.j3ms.n.gmail.com@kernel.org> writes:
>> [...]
>>>> +    fn impl_try_from(
>>>> +        enum_ident: &Ident,
>>>> +        variants: &[Ident],
>>>> +        repr_ty: &syn::Path,
>>>> +        input_ty: &ValidTy,
>>>> +    ) -> TokenStream {
>>>> +        let param = Ident::new("value", Span::call_site());
>>>> +
>>>> +        let overflow_assertion = emit_overflow_assert(enum_ident, variants, repr_ty, input_ty);
>>>> +        let emit_cast = |variant| {
>>>> +            let variant = ::quote::quote! { #enum_ident::#variant };
>>>> +            match input_ty {
>>>> +                ValidTy::Bounded(inner) => {
>>>> +                    let base_ty = inner.emit_qualified_base_ty();
>>>> +                    let expr = parse_quote! { #variant as #base_ty };
>>>> +                    inner.emit_new(&expr)
>>>> +                }
>>>> +                ValidTy::Primitive(ident) if ident == "bool" => {
>>>> +                    ::quote::quote! { ((#variant as #repr_ty) == 1) }
>>>> +                }
>>>> +                qualified @ ValidTy::Primitive(_) => ::quote::quote! { #variant as #qualified },
>>>> +            }
>>>> +        };
>>>> +
>>>> +        let clauses = variants.iter().map(|variant| {
>>>> +            let cast = emit_cast(variant);
>>>> +            ::quote::quote! {
>>>> +                if #param == #cast {
>>>> +                    ::core::result::Result::Ok(#enum_ident::#variant)
>>>> +                } else
>>>> +            }
>>>> +        });
>>>> +
>>>> +        ::quote::quote! {
>>>> +            #[automatically_derived]
>>>> +            impl ::core::convert::TryFrom<#input_ty> for #enum_ident {
>>>> +                type Error = ::kernel::prelude::Error;
>>>> +                fn try_from(#param: #input_ty) -> Result<#enum_ident, Self::Error> {
>>>> +                    #overflow_assertion
>>>> +
>>>> +                    #(#clauses)* {
>>>> +                        ::core::result::Result::Err(::kernel::prelude::EINVAL)
>>>
>>> What happens if we need a different error type here? For example, a
>>> quick look around in nova-core's "Chipset" enum, an unrecognized chipset
>>> ID warrants ENODEV rather than EINVAL, since it's about device
>>> identification.
>>>
>>> Not sure if it fits the design, just wondering if this flexibility would
>>> be useful, but would something like an optional
>>>
>>>     error = <ERROR>
>>>
>>> in the
>>>
>>>    #[try_from(...)]
>>>
>>> attribute make sense? e.g.
>>>
>>>    #[try_from(u32, error = ENODEV)]
>>>
>>> defaulting ofcourse to EINVAL if unspecified.
>>
>> I believe this is indeed a desired change.
>>
>> Back in September, an RFC [1] using the same API (i.e., without error
>> customization) was sent; I took a quick look at the time and felt
>> everything was OK, but in hindsight, the need for this flexibility is
>> clear.
>>
>> Your proposed API looks good to me. Unless there are objections, I'll
>> move forward with this approach.
>
> One problem I can see is that ultimately the error depends on the
> context of the call, not the type itself.
>
> Nova-core's `Chipset` returning `ENODEV` is a bit too opportunistic to
> me - the only place where we are doing the conversion is within probe,
> and that's the error that probe is expected to return. But in another
> context (say, validating some user input), `EINVAL` could be the right
> error to return.
>
> There is technically only one reason for the derived `TryFrom`
> implementations to fail, and that's because the passed value doesn't
> exist in the enum. So really what we would ideally want here is a
> conversion method returning an `Option`, like enumn's `n` [1], that we
> `ok_or` into the correct error for the context.

Good one yes. This is a cleaner approach. Decoupling the error from the
type and letting the caller decode via ok_or looks better to me.

>
> But short of that, I guess we could also have a dedicated, single-value
> error type for derived `TryFrom` implementations that we `map_err`. That
> type could even have an `Into<Error>` implementation that converts it to
> `EINVAL` by default, as that's going to be the most common case.
>
> ... but if we do that, that's not very different from returning `EINVAL`
> and having callers `map_err` on that when they need it.
>
> [1] https://docs.rs/enumn/latest/enumn/

  reply	other threads:[~2026-02-17  2:45 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-29 14:32 [PATCH v5 0/4] rust: add `TryFrom` and `Into` derive macros Jesung Yang via B4 Relay
2026-01-29 14:32 ` [PATCH v5 1/4] rust: macros: add derive macro for `Into` Jesung Yang via B4 Relay
2026-01-29 16:11   ` Charalampos Mitrodimas
2026-01-30 10:03     ` Jesung Yang
2026-01-29 14:32 ` [PATCH v5 2/4] rust: macros: add derive macro for `TryFrom` Jesung Yang via B4 Relay
2026-02-04  1:39   ` Charalampos Mitrodimas
2026-02-05 21:06     ` Jesung Yang
2026-02-17  1:55       ` Alexandre Courbot
2026-02-17  2:45         ` Charalampos Mitrodimas [this message]
2026-01-29 14:32 ` [PATCH v5 3/4] rust: macros: add private doctests for `Into` derive macro Jesung Yang via B4 Relay
2026-01-29 14:32 ` [PATCH v5 4/4] rust: macros: add private doctests for `TryFrom` " Jesung Yang via B4 Relay
2026-02-03 12:48 ` [PATCH v5 0/4] rust: add `TryFrom` and `Into` derive macros shivam kalra
2026-02-28  5:31 ` Alexandre Courbot
2026-02-28  5:33   ` Alexandre Courbot
2026-03-20 10:04   ` Jesung Yang
2026-03-22  6:14     ` Jesung Yang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874ingf5qe.fsf@posteo.net \
    --to=charmitro@posteo.net \
    --cc=a.hindborg@kernel.org \
    --cc=acourbot@nvidia.com \
    --cc=aliceryhl@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=dakr@kernel.org \
    --cc=gary@garyguo.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lossin@kernel.org \
    --cc=nouveau@lists.freedesktop.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tmgross@umich.edu \
    --cc=y.j3ms.n@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox