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: 6+ 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-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
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®