From: Gary Guo <gary@garyguo.net>
To: "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,
Gary Guo <gary@garyguo.net>
Subject: [PATCH v2 3/3] rust: str: convert `as_char_ptr` to work with `const_call!`
Date: Thu, 03 Sep 2026 16:21:46 +0100 [thread overview]
Message-ID: <20260903-cv-v2-3-e93b1613e40c@garyguo.net> (raw)
In-Reply-To: <20260903-cv-v2-0-e93b1613e40c@garyguo.net>
This allows `const_call!(foo.as_char_ptr())` to be used instead of
`kernel::str::as_char_ptr_in_const_context`.
`Const(foo).as_char_ptr()` is used directly in macros to avoid having to
import `CStrExt`.
Signed-off-by: Gary Guo <gary@garyguo.net>
---
rust/kernel/configfs.rs | 2 +-
rust/kernel/drm/device.rs | 4 ++--
rust/kernel/drm/ioctl.rs | 4 ++--
rust/kernel/kunit.rs | 6 +++---
rust/kernel/miscdevice.rs | 2 +-
rust/kernel/net/phy.rs | 2 +-
rust/kernel/str.rs | 15 +++++++--------
rust/macros/lib.rs | 9 +++++++++
rust/macros/module.rs | 4 ++--
9 files changed, 28 insertions(+), 20 deletions(-)
diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
index cd082b83e9e7..ece6cb31609f 100644
--- a/rust/kernel/configfs.rs
+++ b/rust/kernel/configfs.rs
@@ -612,7 +612,7 @@ impl<const ID: u64, O, Data> Attribute<ID, O, Data>
pub const fn new(name: &'static CStr) -> Self {
Self {
attribute: Opaque::new(bindings::configfs_attribute {
- ca_name: crate::str::as_char_ptr_in_const_context(name),
+ ca_name: const_call!(name.as_char_ptr()),
ca_owner: core::ptr::null_mut(),
ca_mode: 0o660,
show: Some(Self::show),
diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs
index 6b88ade28e24..536a0e958c8b 100644
--- a/rust/kernel/drm/device.rs
+++ b/rust/kernel/drm/device.rs
@@ -186,8 +186,8 @@ const fn compute_features() -> u32 {
major: T::INFO.major,
minor: T::INFO.minor,
patchlevel: T::INFO.patchlevel,
- name: crate::str::as_char_ptr_in_const_context(T::INFO.name).cast_mut(),
- desc: crate::str::as_char_ptr_in_const_context(T::INFO.desc).cast_mut(),
+ name: const_call!(T::INFO.name.as_char_ptr()).cast_mut(),
+ desc: const_call!(T::INFO.desc.as_char_ptr()).cast_mut(),
driver_features: Self::compute_features(),
ioctls: T::IOCTLS.as_ptr(),
diff --git a/rust/kernel/drm/ioctl.rs b/rust/kernel/drm/ioctl.rs
index 64af9eacc306..5bba960504d6 100644
--- a/rust/kernel/drm/ioctl.rs
+++ b/rust/kernel/drm/ioctl.rs
@@ -206,9 +206,9 @@ macro_rules! declare_drm_ioctls {
Some($cmd)
},
flags: $flags,
- name: $crate::str::as_char_ptr_in_const_context(
+ name: $crate::const_eval::Const(
$crate::c_str!(::core::stringify!($cmd)),
- ),
+ ).as_char_ptr(),
}
),*];
ioctls
diff --git a/rust/kernel/kunit.rs b/rust/kernel/kunit.rs
index 91eaff8c186a..034df521b195 100644
--- a/rust/kernel/kunit.rs
+++ b/rust/kernel/kunit.rs
@@ -107,12 +107,12 @@ unsafe impl Sync for Location {}
unsafe impl Sync for UnaryAssert {}
static LOCATION: Location = Location($crate::bindings::kunit_loc {
- file: $crate::str::as_char_ptr_in_const_context(FILE),
+ file: $crate::const_eval::Const(FILE).as_char_ptr(),
line: LINE,
});
static ASSERTION: UnaryAssert = UnaryAssert($crate::bindings::kunit_unary_assert {
assert: $crate::bindings::kunit_assert {},
- condition: $crate::str::as_char_ptr_in_const_context(CONDITION),
+ condition: $crate::const_eval::Const(CONDITION).as_char_ptr(),
expected_true: true,
});
@@ -204,7 +204,7 @@ pub const fn kunit_case(
) -> kernel::bindings::kunit_case {
kernel::bindings::kunit_case {
run_case: Some(run_case),
- name: kernel::str::as_char_ptr_in_const_context(name),
+ name: const_call!(name.as_char_ptr()),
attr: kernel::bindings::kunit_attributes {
speed: kernel::bindings::kunit_speed_KUNIT_SPEED_NORMAL,
},
diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs
index 8d4b719bd83f..02e115ec045d 100644
--- a/rust/kernel/miscdevice.rs
+++ b/rust/kernel/miscdevice.rs
@@ -46,7 +46,7 @@ impl MiscDeviceOptions {
pub const fn into_raw<T: MiscDevice>(self) -> bindings::miscdevice {
let mut result: bindings::miscdevice = pin_init::zeroed();
result.minor = bindings::MISC_DYNAMIC_MINOR as ffi::c_int;
- result.name = crate::str::as_char_ptr_in_const_context(self.name);
+ result.name = const_call!(self.name.as_char_ptr());
result.fops = MiscdeviceVTable::<T>::build();
result
}
diff --git a/rust/kernel/net/phy.rs b/rust/kernel/net/phy.rs
index 956cda573ddb..28047fc3a876 100644
--- a/rust/kernel/net/phy.rs
+++ b/rust/kernel/net/phy.rs
@@ -494,7 +494,7 @@ unsafe impl Sync for DriverVTable {}
pub const fn create_phy_driver<T: Driver>() -> DriverVTable {
// INVARIANT: All the fields of `struct phy_driver` are initialized properly.
DriverVTable(Opaque::new(bindings::phy_driver {
- name: crate::str::as_char_ptr_in_const_context(T::NAME).cast_mut(),
+ name: const_call!(T::NAME.as_char_ptr()).cast_mut(),
flags: T::FLAGS,
phy_id: T::PHY_DEVICE_ID.id(),
phy_id_mask: T::PHY_DEVICE_ID.mask_as_int(),
diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
index b3caa9a1c898..93ae32b42e18 100644
--- a/rust/kernel/str.rs
+++ b/rust/kernel/str.rs
@@ -197,14 +197,13 @@ macro_rules! b_str {
}};
}
-/// Returns a C pointer to the string.
-// It is a free function rather than a method on an extension trait because:
-//
-// - error[E0379]: functions in trait impls cannot be declared const
-#[inline]
-#[expect(clippy::disallowed_methods, reason = "internal implementation")]
-pub const fn as_char_ptr_in_const_context(c_str: &CStr) -> *const c_char {
- c_str.as_ptr().cast()
+impl crate::const_eval::Const<&CStr> {
+ /// Returns a C pointer to the string.
+ #[inline]
+ #[expect(clippy::disallowed_methods, reason = "internal implementation")]
+ pub const fn as_char_ptr(self) -> *const c_char {
+ self.0.as_ptr().cast()
+ }
}
mod private {
diff --git a/rust/macros/lib.rs b/rust/macros/lib.rs
index 262539cccf38..f5d8d0706e46 100644
--- a/rust/macros/lib.rs
+++ b/rust/macros/lib.rs
@@ -343,6 +343,15 @@ pub fn concat_idents(input: TokenStream) -> TokenStream {
///
/// This is a polyfill for Rust's const trait impl feature. Only work for specific methods that have
/// dedicated const implementation.
+///
+/// # Examples
+///
+/// ```
+/// const fn use_cstr(c: &CStr) {
+/// // This is an extension trait method that is not otherwise callable in const context.
+/// let char_ptr = const_call!((c).as_char_ptr());
+/// }
+/// ```
#[proc_macro]
pub fn const_call(input: TokenStream) -> TokenStream {
const_eval::const_call(parse_macro_input!(input)).into()
diff --git a/rust/macros/module.rs b/rust/macros/module.rs
index bc7027f8dbb2..b2c1f118c7e1 100644
--- a/rust/macros/module.rs
+++ b/rust/macros/module.rs
@@ -149,13 +149,13 @@ fn emit_params(&mut self, info: &ModuleInfo) {
::kernel::module_param::KernelParam =
::kernel::module_param::KernelParam::new(
::kernel::bindings::kernel_param {
- name: kernel::str::as_char_ptr_in_const_context(
+ name: ::kernel::const_eval::Const(
if ::core::cfg!(MODULE) {
#param_name_cstr
} else {
#param_name_cstr_with_module
}
- ),
+ ).as_char_ptr(),
// SAFETY: `__this_module` is constructed by the kernel at load
// time and will not be freed until the module is unloaded.
#[cfg(MODULE)]
--
2.54.0
next prev parent reply other threads:[~2026-09-03 15:22 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
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 ` Gary Guo [this message]
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=20260903-cv-v2-3-e93b1613e40c@garyguo.net \
--to=gary@garyguo.net \
--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=ecourtney@nvidia.com \
--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.