Skip to content

Commit 2502015

Browse files
committed
rust: add TryFrom and Into derive macros
This patch series introduces derive macros for the `TryFrom` and `Into` traits. Main changes in v6: - `#[convert(..)]`, a new helper attribute both works for `TryFrom` and `Into` derive macro, has been introduced. This helps avoid repeating the same types in `#[into(..)]` and `#[try_from(..)]`. The example of using this feature can be found in the docs. - Dependency on `Bounded::from_expr` has been replaced with a match expression with `Bounded::new`. Since we pass a numerical representation of each variant (a.k.a. discriminant) down as a const generic argument, the inner const block of `Bounded::new` is guaranteed to be run at compile time. As a result, we don't have to worry about `build_assert!()` in `Bounded::from_expr`, which relies on (unpredictable) compiler optimization to successfully build. The above two changes are derived mainly from Alexandre's feedback. Thanks for sharing the idea! @Shivam I dropped your Tested-by since I added/changed some tests to cover the new feature introduced in this version. Thanks for your previous effort to test the series! --- TODO: remove the following when sending v6 --- I dropped support for `#[repr(C)]` fieldless enums (i.e., disallow deriving `TryFrom` and `Into` on those enums), since the actual representation of discriminants is defined by rustc internally, and documentation around it is not yet settled [1][2]. I would like to highlight some feedback from the previous series where I have decided to retain the original behavior in this series. In part, I feel more community feedback is needed to reach the right design; I've also elaborated on my personal reasoning for each point below: 1) Require explicit `#[repr(..)]` for enums using the macros. Given the drop of `#[repr(C)]` support, I believe defaulting to `isize` when no `#[repr(..)]` is specified is safe, as it follows the compiler's (documented) default behavior [3]. By "safe", I mean I see no potential regressions or hidden issues; we even have a compile-time overflow assertion which ensure all enum discriminants fit within the types involved in the conversion. 2) Generate trait implementation for a type in `#[repr(..)]` even when the helper attribute is present. For example: #[derive(TryFrom)] #[try_from(bool)] #[repr(u8)] enum E { A = 0, B = 1, } make the above snippet generate both `TryFrom<u8>` and `TryFrom<bool>` implementations. However, sometimes users might want to prevent generating trait implementations for the type in `#[repr(..)]`, especially when the enum encodes types like `bool` or `Bounded<u8, 4>` that cannot be used in `#[repr(..)]`, like the above snippet. If we were to follow the feedback directly, users would end up with an unnecessary `TryFrom<u8>` implementation. Therefore, I think it is reasonable to treat the helper attribute as an override that ignores the type in `#[repr(..)]` when present. [1] rust-lang/rust#124403 [2] rust-lang/rust#147017 [3] https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.repr-rust To: Miguel Ojeda <ojeda@kernel.org> To: Boqun Feng <boqun.feng@gmail.com> To: Gary Guo <gary@garyguo.net> To: Björn Roy Baron <bjorn3_gh@protonmail.com> To: Benno Lossin <lossin@kernel.org> To: Andreas Hindborg <a.hindborg@kernel.org> To: Alice Ryhl <aliceryhl@google.com> To: Trevor Gross <tmgross@umich.edu> To: Danilo Krummrich <dakr@kernel.org> To: Alexandre Courbot <acourbot@nvidia.com> To: Charalampos Mitrodimas <charmitro@posteo.net> To: Shivam Kalra <shivamklr@cock.li> Cc: linux-kernel@vger.kernel.org Cc: rust-for-linux@vger.kernel.org Cc: nouveau@lists.freedesktop.org Signed-off-by: Jesung Yang <y.j3ms.n@gmail.com> --- Changes in v6: - Introduce `#[convert(..)]`, a common helper attribute. (Alexandre Courbot) - Update docs and tests for `#[convert(..)]`. - Remove dependency on `Bounded::from_expr`. (Alexandre Courbot) - Fix user-facing doctests for `#[repr(C)]` fieldless enums. (Charalampos Mitrodimas) - Minor variable name refactoring. - Link to v5: https://lore.kernel.org/r/20260129-try-from-into-macro-v5-0-dd011008118c@gmail.com Changes in v5: - Drop support for `#[repr(C)]` enums. (Benno Lossin) - Allow `#[repr(C, {primitive_int_type})]` for future-proofing. (Benno Lossin) - Parse types in helper attributes into `syn::Type` prior to validation. (Benno Lossin) - Replace doctests for `TryFrom` with correct examples. (Benno Lossin) - Reorganize error reporting structure. - Add documentation about `#[repr(C)]` fieldless enums. - Rebase on commit a7c013f ("Merge patch series "refactor Rust proc macros with `syn`"") - Link to v4: https://lore.kernel.org/r/20251225-try-from-into-macro-v4-0-4a563d597836@gmail.com Changes in v4: - Fix typos. - Link to (broken) v3: https://lore.kernel.org/rust-for-linux/cover.1766544407.git.y.j3ms.n@gmail.com/ Changes in v3: - Use the vendored `syn` and `quote` crates. - Support `kernel::num::Bounded`. - Add compile-time overflow assertion. - Add a comment about `#[repr(C)]` enums. - Drop Tested-by and Reviewed-by tags, as the code structure has changed substantially. (Thanks for the previous reviews and testing!) - Link to v2: https://lore.kernel.org/rust-for-linux/cover.1755235180.git.y.j3ms.n@gmail.com/ Changes in v2 (no functional changes): - Split the patch "rust: macros: extend custom `quote!()` macro" into two separate patches. - Remove unnecessary spaces between tags. - Use a consistent commit subject prefix: "rust: macros:". - Add Tested-by tags. - Link to v1: https://lore.kernel.org/rust-for-linux/cover.1754228164.git.y.j3ms.n@gmail.com/ --- b4-submit-tracking --- # This section is used internally by b4 prep for tracking purposes. { "series": { "revision": 6, "change-id": "20251225-try-from-into-macro-1665d0afcfc8", "prefixes": [], "history": { "v4": [ "20251225-try-from-into-macro-v4-0-4a563d597836@gmail.com" ], "v5": [ "20260129-try-from-into-macro-v5-0-dd011008118c@gmail.com" ] } } }
1 parent a7c013f commit 2502015

0 file changed

File tree

    0 commit comments

    Comments
     (0)