From: Kaiqi Guo <chaoji_xinren@163.com>
To: rust-for-linux@vger.kernel.org, Miguel Ojeda <ojeda@kernel.org>
Cc: Jesung Yang <y.j3ms.n@gmail.com>,
Alexandre Courbot <acourbot@nvidia.com>,
Danilo Krummrich <dakr@kernel.org>,
nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org,
linux-kernel@vger.kernel.org, Kaiqi Guo <chaoji_xinren@163.com>
Subject: [PATCH v6 09/10] rust: macros: validate and qualify conversion helper types
Date: Tue, 29 Sep 2026 21:58:54 +0800 [thread overview]
Message-ID: <20260929135855.36775-10-chaoji_xinren@163.com> (raw)
In-Reply-To: <20260929135855.36775-1-chaoji_xinren@163.com>
Reject generic arguments attached to a primitive helper input.
Previously bool<Undefined> was silently treated as bool because only the
final identifier was validated.
Qualify Result in generated TryFrom signatures and the backing primitive
passed to Bounded::new. Local aliases named Result or u8 must not alter
the implementation after its input was validated as a primitive. Add
compile-pass and compile-fail regressions for each case.
Signed-off-by: Kaiqi Guo <chaoji_xinren@163.com>
---
rust/macros/convert.rs | 52 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 50 insertions(+), 2 deletions(-)
diff --git a/rust/macros/convert.rs b/rust/macros/convert.rs
index c23b8819572e..0fda475349ef 100644
--- a/rust/macros/convert.rs
+++ b/rust/macros/convert.rs
@@ -295,7 +295,7 @@ fn impl_try_from(
#[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> {
+ fn try_from(#param: #input_ty) -> ::core::result::Result<#enum_ident, Self::Error> {
#overflow_assertion
#(#clauses)* {
@@ -492,7 +492,8 @@ impl Bounded {
const QUALIFIED_NAME: &'static str = "::kernel::num::Bounded";
fn emit_new(&self, expr: &Expr) -> TokenStream {
- let Self { base_ty, bits, .. } = self;
+ let base_ty = self.emit_qualified_base_ty();
+ let bits = &self.bits;
let qualified_name: syn::Path = parse_str(Self::QUALIFIED_NAME).expect("valid path");
::quote::quote! {
#qualified_name::<#base_ty, #bits>::new::<{ #expr }>()
@@ -556,6 +557,8 @@ fn validate_type(ty: &Type) -> syn::Result<ValidTy> {
let segment = &path.segments[0];
if segment.ident == Bounded::NAME {
return validate_bounded(segment);
+ } else if !matches!(segment.arguments, PathArguments::None) {
+ return Err(make_err(ty));
} else {
return validate_primitive(&segment.ident);
}
@@ -2043,3 +2046,48 @@ mod incomplete_wide_input_8 {}
/// ```
mod incomplete_wide_input_9 {}
}
+
+mod helper_type_tests {
+ /// ```compile_fail
+ /// use kernel::macros::Into;
+ /// #[derive(Into)]
+ /// #[into(bool<Undefined>)]
+ /// enum Invalid { A, B }
+ /// ```
+ ///
+ /// ```compile_fail
+ /// use kernel::macros::TryFrom;
+ /// #[derive(TryFrom)]
+ /// #[try_from(bool<Undefined>)]
+ /// enum Invalid { A, B }
+ /// ```
+ ///
+ /// ```compile_fail
+ /// use kernel::macros::From;
+ /// #[derive(From)]
+ /// #[from(bool<Undefined>)]
+ /// enum Invalid { A, B }
+ /// ```
+ mod primitive_arguments_are_not_ignored {}
+
+ /// ```
+ /// #![allow(non_camel_case_types, dead_code)]
+ /// use kernel::{macros::{From, Into, TryFrom}, num::Bounded};
+ ///
+ /// type Result = ();
+ /// type u8 = i8;
+ ///
+ /// #[derive(Debug, PartialEq, From, Into, TryFrom)]
+ /// #[from(Bounded<u8, 1>)]
+ /// #[into(Bounded<u8, 1>)]
+ /// #[try_from(u8, Bounded<u8, 2>)]
+ /// enum Switch { Off, On }
+ ///
+ /// let value = Bounded::<core::primitive::u8, 1>::new::<1>();
+ /// assert_eq!(Switch::from(value), Switch::On);
+ /// assert_eq!(Bounded::<core::primitive::u8, 1>::from(Switch::On), value);
+ /// assert_eq!(Switch::try_from(0_u8), Ok(Switch::Off));
+ /// assert_eq!(Switch::try_from(value.extend::<2>()), Ok(Switch::On));
+ /// ```
+ mod names_in_scope_do_not_change_generated_types {}
+}
next prev parent reply other threads:[~2026-09-29 13:59 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-29 13:58 [PATCH v6 00/10] rust: add conversion derives and exhaustive From support Kaiqi Guo
2026-09-29 13:58 ` [PATCH v6 01/10] rust: macros: add derive macro for `Into` Kaiqi Guo
2026-09-29 13:58 ` [PATCH v6 02/10] rust: macros: add derive macro for `TryFrom` Kaiqi Guo
2026-09-29 13:58 ` [PATCH v6 03/10] rust: macros: add `convert` helper attribute Kaiqi Guo
2026-09-29 13:58 ` [PATCH v6 04/10] rust: macros: add private doctests for `Into` derive macro Kaiqi Guo
2026-09-29 13:58 ` [PATCH v6 05/10] rust: macros: add private doctests for `TryFrom` " Kaiqi Guo
2026-09-29 13:58 ` [PATCH v6 06/10] rust: macros: exercise the intended conversion doctest failures Kaiqi Guo
2026-09-29 18:47 ` Miguel Ojeda
2026-09-29 13:58 ` [PATCH v6 07/10] rust: macros: derive From for exhaustive enum conversions Kaiqi Guo
2026-09-29 13:58 ` [PATCH v6 08/10] rust: macros: test exhaustive conversion derives Kaiqi Guo
2026-09-29 13:58 ` Kaiqi Guo [this message]
2026-09-29 13:58 ` [PATCH v6 10/10] gpu: nova-core: use conversion derives for two register enums Kaiqi Guo
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=20260929135855.36775-10-chaoji_xinren@163.com \
--to=chaoji_xinren@163.com \
--cc=acourbot@nvidia.com \
--cc=dakr@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nova-gpu@lists.linux.dev \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--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