Re: [PATCH v5 0/4] rust: add `TryFrom` and `Into` derive macros
From: Jesung Yang
Date: Fri Mar 20 2026 - 06:07:43 EST
Apologies for the delay.
On Sat Feb 28, 2026 at 2:31 PM KST, Alexandre Courbot wrote:
[...]
> FWIW I have converted nova-core to use this, and this results in -200LoC
> delta. Obviously I like this very much. :)
>
> A few pieces of feedback for things I noticed while doing the
> conversion:
>
> - Very often we need to convert a type from and into the same primitive.
> Not having to repeat the same thing in `#[try_from(foo)]` and
> `#[into(foo)]` for these cases would be nice.
I think I can add a common attribute that works for both `TryFrom` and
`Into`, e.g. `#[convert(foo)]`.
> - In some rare cases, we want to convert an enum with 4 variants into
> e.g. a `Bounded<u8, 2>`. This can be done using a `From`
> implementation, and that's what the register macro expects. These
> cases are not covered by the current macro (they are few however).
I think you can just do the following?:
#[derive(Into)]
#[into(Bounded<u8, 2>)]
enum Enum {
A,
B,
C,
D,
}
let a = Bounded::<u8, 2>::from(Enum::A);
// or let a: Bounded<u8, 2> = Enum::A.into();
This works because `Into` actually generates the `From<Enum>`
implementation for `Bounded<u8, 2>`.
> - When converting from/into boundeds, the number of used bits is the
> only thing that counts - the backing type (u8, u32, ...) is
> irrelevant. I thought it would be cool to be able to have a generic
> TryFrom/Into implementation that works irrespective of the backing
> type, but as far as I can tell this would be difficult to achieve.
> Just throwing the idea in case others are more inspired than I am. :)
Yeah, it seems difficult to me as well since those macros need the
full type information to generate the trait implementations.
>> One last point: the current `Into` implementation relies on
>> `Bounded::from_expr()`, which utilizes `build_assert!()`. So the
>> expanded result looks roughly like this:
>>
>> impl From<Enum> for Bounded<u8, 4> {
>> fn from(value: Enum) -> Bounded<u8, 4> {
>> // Compile-time assertions to guarantee `value` fits within
>> // `u8` (Omitted)
>>
>> Bounded::<u8, 4>::from_expr(value as u8)
>> }
>> }
>>
>> After some experimentation, it appears that the compiler correctly
>> optimizes out the assertion if (and only if) the `Bounded` type covers
>> all enum discriminants, though I'm not 100% certain of this behavior in
>> all cases. Can we approach this better?
>
> I think you should also be able to have a match arm for all variants and
> call the `Bounded::new` const method - hopefully the compiler will
> optimize that as well. That or rely on unsafe code and a (hypothetical)
> `new_unchecked` constructor for Bounded, since the macro can infer that
> its invariants are respected.
This looks much better. Thanks for the idea!
I'll update the implementation based on your feedback within this week,
but I'd like to ping Benno first to check whether he's satisfied with
this v5 before I send those new changes.
Thanks for your patience.
Best regards,
Jesung