From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 53AB15304C5; Tue, 29 Sep 2026 13:59:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.3 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790690402; cv=none; b=heympvTeA+xyaIWnWr20+TUF11hnCPevMsNiOFzLOL7U0/tFUYtW9y0bRTOdjG20DzWuHT7CUwpSHO4rQlBL30YY2M1sTMUZN21xMeibg8O2O6Dh+2Gi/RYtg7i2tXfgHBlb567RNqtP0Pjyks39sJo+W+V/hWzarDgFkltzvH8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790690402; c=relaxed/simple; bh=KP/jBAzSPaGaYf4HT39f9eKG4rN6YxXi/hZZz3cCd5M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MhHDVvsnNHIIZM0BzXH6o8eHrESFZZbjBz/EHWA/ipyVYg51AAnlt44R7BzLd/JRsFNRNMzDbHOceWypsF/8XwECuQoUluNNhQEgtU2TtJwoA5qPsaa/234o5zoFWF7W7YEEClv+V+OaGurD9+Xn3hQBvx5o8IM4jGdN1r+WsF4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=ohsPFxIw; arc=none smtp.client-ip=220.197.31.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="ohsPFxIw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=9J Yc+I4fx493tzaiB9uX+d69rIo9laChvTEy0umgPdg=; b=ohsPFxIw0mSRLy0lqC k1LA+O0K1ThmJJ+GYuSi8vvV32aHz3LkWxLMTFxUqYDUoeShxdsIBj9ZydEQc2sY hLHmok2vTURuxex7GVLoB7NOjjekDkD9FblV0bEjtU68xjMjMEVm8aVqGyJh7Rur 0ZcWP7XbgKRcH2EB2YYX1i9vs= Received: from localhost.localdomain (unknown []) by gzga-smtp-mtada-g0-4 (Coremail) with SMTP id _____wD3rr08xLtqmCNYBg--.46271S6; Tue, 29 Sep 2026 21:59:37 +0800 (CST) From: Kaiqi Guo To: rust-for-linux@vger.kernel.org, Miguel Ojeda Cc: Jesung Yang , Alexandre Courbot , Danilo Krummrich , nova-gpu@lists.linux.dev, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Kaiqi Guo Subject: [PATCH v6 09/10] rust: macros: validate and qualify conversion helper types Date: Tue, 29 Sep 2026 21:58:54 +0800 Message-ID: <20260929135855.36775-10-chaoji_xinren@163.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20260929135855.36775-1-chaoji_xinren@163.com> References: <20260929135855.36775-1-chaoji_xinren@163.com> Precedence: bulk X-Mailing-List: rust-for-linux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID:_____wD3rr08xLtqmCNYBg--.46271S6 X-Coremail-Antispam: 1Uf129KBjvJXoWxAr17Kw4UWFy7KF13ArWfGrg_yoW5tF48pr WUC3yagFW7J343Gay3Kw47X3yS9FWfX3W5GFZrG3ySvF45WF4kWr42gr1fJryrKr4DAr9I 9ryqqayDG34jy37anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0pE_OzhUUUUU= X-CM-SenderInfo: pfkd0yplb0x0xuhqqiywtou0bp/xtbC-QnMSGq7xEmrYwAA3k Reject generic arguments attached to a primitive helper input. Previously bool 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 --- 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 { 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)] + /// enum Invalid { A, B } + /// ``` + /// + /// ```compile_fail + /// use kernel::macros::TryFrom; + /// #[derive(TryFrom)] + /// #[try_from(bool)] + /// enum Invalid { A, B } + /// ``` + /// + /// ```compile_fail + /// use kernel::macros::From; + /// #[derive(From)] + /// #[from(bool)] + /// 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)] + /// #[into(Bounded)] + /// #[try_from(u8, Bounded)] + /// enum Switch { Off, On } + /// + /// let value = Bounded::::new::<1>(); + /// assert_eq!(Switch::from(value), Switch::On); + /// assert_eq!(Bounded::::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 {} +}