From: "Eliot Courtney" <ecourtney@nvidia.com>
To: "Gary Guo" <gary@garyguo.net>,
"Eliot Courtney" <ecourtney@nvidia.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Boqun Feng" <boqun@kernel.org>,
"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>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
"Tamir Duberstein" <tamird@kernel.org>,
"Alexandre Courbot" <acourbot@nvidia.com>,
"Onur Özkan" <work@onurozkan.dev>
Cc: <linux-kernel@vger.kernel.org>, <rust-for-linux@vger.kernel.org>
Subject: Re: [PATCH v2 1/3] rust: const_eval: add `#[const_eval_only]` attribute
Date: Mon, 07 Sep 2026 17:45:30 +0900 [thread overview]
Message-ID: <DL8YAXFG28GT.11FRAWC7NUBM7@nvidia.com> (raw)
In-Reply-To: <20260903-cv-v2-1-e93b1613e40c@garyguo.net>
On Fri Sep 4, 2026 at 12:21 AM JST, Gary Guo wrote:
> We have a lot of helper const functions which are intended to be used
> during const evaluation only and runtime calls should not be generated. Add
> a macro to denote this explicitly. This is similar to C++'s consteval
> keyword.
>
> Convert device_id.rs as an example.
>
> Signed-off-by: Gary Guo <gary@garyguo.net>
> ---
> rust/build_error.rs | 7 +++++++
> rust/kernel/const_eval.rs | 9 +++++++++
> rust/kernel/device_id.rs | 4 ++++
> rust/kernel/lib.rs | 1 +
> rust/macros/const_eval.rs | 24 ++++++++++++++++++++++++
> rust/macros/lib.rs | 21 +++++++++++++++++++++
> 6 files changed, 66 insertions(+)
>
> diff --git a/rust/build_error.rs b/rust/build_error.rs
> index fa24eeef9929..b7ef80596f1f 100644
> --- a/rust/build_error.rs
> +++ b/rust/build_error.rs
> @@ -29,3 +29,10 @@
> pub const fn build_error(msg: &'static str) -> ! {
> panic!("{}", msg);
> }
> +
> +/// Assert that the code is in const evaluation.
> +///
> +/// Triggers a build error if called at runtime.
> +#[inline(never)]
> +#[export_name = "rust_const_eval_called_at_runtime"]
> +pub const fn assert_in_const_eval() {}
IIUC if RUST_BUILD_ASSERT_ALLOW=y then this will not cause a build error
anything built-in. I don't expect the call will ever fail to be
eliminated by link time here, so isn't it better to not use the same
mechanism affected by RUST_BUILD_ASSERT_ALLOW=y here? Guess you would
need to make a new file for this.
> diff --git a/rust/kernel/const_eval.rs b/rust/kernel/const_eval.rs
> new file mode 100644
> index 000000000000..f1b79d82549d
> --- /dev/null
> +++ b/rust/kernel/const_eval.rs
> @@ -0,0 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +//! Utilities for const evaluation.
> +
> +#[doc(inline)]
> +pub use build_error::assert_in_const_eval;
> +
> +#[doc(inline)]
> +pub use macros::const_eval_only;
> diff --git a/rust/kernel/device_id.rs b/rust/kernel/device_id.rs
> index c81fca5b4986..dad9cadaeb1b 100644
> --- a/rust/kernel/device_id.rs
> +++ b/rust/kernel/device_id.rs
> @@ -10,6 +10,8 @@
> mem::MaybeUninit, //
> };
>
> +use crate::const_eval::const_eval_only;
I am used to C++ so #[consteval] looks nicer to me (same with Miguel)
but no idea if that means it's better. Just another datapoint.
> +
> /// Marker trait to indicate a Rust device ID type represents a corresponding C device ID type.
> ///
> /// This is meant to be implemented by buses/subsystems so that they can use [`IdTable`] to
> @@ -108,6 +110,7 @@ impl<T: RawDeviceId + RawDeviceIdIndex, U: 'static, const N: usize> IdArray<T, U
> /// Creates a new instance of the array.
> ///
> /// The contents are derived from the given identifiers and context information.
> + #[const_eval_only]
> pub const fn new(ids: [(T, &'static U); N]) -> Self {
> let mut raw_ids = [const { MaybeUninit::<T::RawType>::uninit() }; N];
>
> @@ -144,6 +147,7 @@ impl<T: RawDeviceId, const N: usize> IdArray<T, (), N> {
> ///
> /// The contents are derived from the given identifiers and context information.
> /// If the device implements [`RawDeviceIdIndex`], consider using [`IdArray::new`] instead.
> + #[const_eval_only]
> pub const fn new_without_index(ids: [T; N]) -> Self {
> // SAFETY: `T` is layout-wise compatible with `T::RawType`, so is the array of them.
> let raw_ids: [MaybeUninit<T::RawType>; N] = unsafe { core::mem::transmute_copy(&ids) };
> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> index 4d5c96ddc49c..d9ed25e96ff3 100644
> --- a/rust/kernel/lib.rs
> +++ b/rust/kernel/lib.rs
> @@ -57,6 +57,7 @@
> pub mod clk;
> #[cfg(CONFIG_CONFIGFS_FS)]
> pub mod configfs;
> +pub mod const_eval;
> pub mod cpu;
> #[cfg(CONFIG_CPU_FREQ)]
> pub mod cpufreq;
> diff --git a/rust/macros/const_eval.rs b/rust/macros/const_eval.rs
> new file mode 100644
> index 000000000000..0664888d3b38
> --- /dev/null
> +++ b/rust/macros/const_eval.rs
> @@ -0,0 +1,24 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +use proc_macro2::TokenStream;
> +use quote::ToTokens;
> +use syn::{
> + parse_quote,
> + ItemFn, //
> +};
> +
> +pub(crate) fn const_eval_only(mut input: ItemFn) -> TokenStream {
> + // Prevent code generation as the function is for const evaluation only.
> + input.attrs.push(parse_quote!(
> + #[inline(always)]
> + ));
> +
> + input.block.stmts.insert(
> + 0,
> + parse_quote!(
> + ::kernel::const_eval::assert_in_const_eval();
> + ),
> + );
> +
> + input.into_token_stream()
> +}
> diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs
> index 24f96feaeb34..e47a8c35ccff 100644
> --- a/rust/macros/lib.rs
> +++ b/rust/macros/lib.rs
> @@ -15,6 +15,7 @@
> #![cfg_attr(not(CONFIG_RUSTC_HAS_SPAN_FILE), feature(proc_macro_span))]
>
> mod concat_idents;
> +mod const_eval;
> mod export;
> mod fmt;
> mod for_lt;
> @@ -338,6 +339,26 @@ pub fn concat_idents(input: TokenStream) -> TokenStream {
> concat_idents::concat_idents(parse_macro_input!(input)).into()
> }
>
> +/// Mark a function as usable from const evaluation only.
> +///
> +/// Build will fail if the function is used for runtime code.
> +///
> +/// # Examples
> +///
> +/// ```
> +/// #[const_eval_only]
> +/// const fn call_for_const_eval_only() {
> +/// // This code will be executed only during const eval!
> +/// }
> +///
> +/// const _: () = call_for_const_eval_only();
> +/// ```
Looks like `make rusttest` fails here?
> +#[proc_macro_attribute]
> +pub fn const_eval_only(attr: TokenStream, input: TokenStream) -> TokenStream {
> + parse_macro_input!(attr as syn::parse::Nothing);
> + const_eval::const_eval_only(parse_macro_input!(input)).into()
> +}
> +
> /// Paste identifiers together.
> ///
> /// Within the `paste!` macro, identifiers inside `[<` and `>]` are concatenated together to form a
I think this is a useful thing to add! Thanks~
next prev parent reply other threads:[~2026-09-07 8:45 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 15:21 [PATCH v2 0/3] rust: const_eval: add a mechanism to do const trait calls Gary Guo
2026-09-03 15:21 ` [PATCH v2 1/3] rust: const_eval: add `#[const_eval_only]` attribute Gary Guo
2026-09-07 8:45 ` Eliot Courtney [this message]
2026-09-09 14:36 ` Gary Guo
2026-09-03 15:21 ` [PATCH v2 2/3] rust: const_eval: allow const trait method invocation in some contexts Gary Guo
2026-09-03 15:21 ` [PATCH v2 3/3] rust: str: convert `as_char_ptr` to work with `const_call!` Gary Guo
2026-09-03 15:34 ` [PATCH v2 0/3] rust: const_eval: add a mechanism to do const trait calls Miguel Ojeda
2026-09-03 15:46 ` Gary Guo
2026-09-07 9:21 ` Eliot Courtney
2026-09-09 14:32 ` Gary 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=DL8YAXFG28GT.11FRAWC7NUBM7@nvidia.com \
--to=ecourtney@nvidia.com \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=gary@garyguo.net \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tamird@kernel.org \
--cc=tmgross@umich.edu \
--cc=work@onurozkan.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.