All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dirk Behme <dirk.behme@gmail.com>
To: "Tamir Duberstein" <tamird@gmail.com>,
	"Michal Rostecki" <vadorovsky@protonmail.com>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <benno.lossin@proton.me>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>
Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v6 3/4] rust: replace `kernel::c_str!` with C-Strings
Date: Sun, 2 Feb 2025 14:10:15 +0100	[thread overview]
Message-ID: <3e2cb277-a896-4575-b23b-8d9b42c87173@gmail.com> (raw)
In-Reply-To: <20250202-cstr-core-v6-3-8469cd6d29fd@gmail.com>

Hi Tamir,

On 02.02.25 13:20, Tamir Duberstein wrote:
> C-String literals were added in Rust 1.77. Replace instances of
> `kernel::c_str!` with C-String literals where possible and rename
> `kernel::c_str!` to `c_str_avoid_literals` to clarify its intended use.
> 
> Closes: https://github.com/Rust-for-Linux/linux/issues/1075
> Signed-off-by: Tamir Duberstein <tamird@gmail.com>
> ---
>  drivers/net/phy/ax88796b_rust.rs |  7 +++----
>  drivers/net/phy/qt2025.rs        |  5 ++---
>  rust/kernel/firmware.rs          |  4 ++--
>  rust/kernel/kunit.rs             |  7 ++++---
>  rust/kernel/net/phy.rs           |  6 ++----
>  rust/kernel/str.rs               | 37 ++++++++++++++++++++++++-------------
>  rust/kernel/sync.rs              |  4 ++--
>  rust/kernel/sync/lock/global.rs  |  3 ++-
>  8 files changed, 41 insertions(+), 32 deletions(-)


Have you checked samples/rust/ [1] as well?

Best regards

Dirk

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/rust


> diff --git a/drivers/net/phy/ax88796b_rust.rs b/drivers/net/phy/ax88796b_rust.rs
> index 8c7eb009d9fc..b07d36f45a43 100644
> --- a/drivers/net/phy/ax88796b_rust.rs
> +++ b/drivers/net/phy/ax88796b_rust.rs
> @@ -5,7 +5,6 @@
>  //!
>  //! C version of this driver: [`drivers/net/phy/ax88796b.c`](./ax88796b.c)
>  use kernel::{
> -    c_str,
>      net::phy::{self, reg::C22, DeviceId, Driver},
>      prelude::*,
>      uapi,
> @@ -41,7 +40,7 @@ fn asix_soft_reset(dev: &mut phy::Device) -> Result {
>  #[vtable]
>  impl Driver for PhyAX88772A {
>      const FLAGS: u32 = phy::flags::IS_INTERNAL;
> -    const NAME: &'static CStr = c_str!("Asix Electronics AX88772A");
> +    const NAME: &'static CStr = c"Asix Electronics AX88772A";
>      const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_exact_mask(0x003b1861);
>  
>      // AX88772A is not working properly with some old switches (NETGEAR EN 108TP):
> @@ -105,7 +104,7 @@ fn link_change_notify(dev: &mut phy::Device) {
>  #[vtable]
>  impl Driver for PhyAX88772C {
>      const FLAGS: u32 = phy::flags::IS_INTERNAL;
> -    const NAME: &'static CStr = c_str!("Asix Electronics AX88772C");
> +    const NAME: &'static CStr = c"Asix Electronics AX88772C";
>      const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_exact_mask(0x003b1881);
>  
>      fn suspend(dev: &mut phy::Device) -> Result {
> @@ -125,7 +124,7 @@ fn soft_reset(dev: &mut phy::Device) -> Result {
>  
>  #[vtable]
>  impl Driver for PhyAX88796B {
> -    const NAME: &'static CStr = c_str!("Asix Electronics AX88796B");
> +    const NAME: &'static CStr = c"Asix Electronics AX88796B";
>      const PHY_DEVICE_ID: DeviceId = DeviceId::new_with_model_mask(0x003b1841);
>  
>      fn soft_reset(dev: &mut phy::Device) -> Result {
> diff --git a/drivers/net/phy/qt2025.rs b/drivers/net/phy/qt2025.rs
> index 1ab065798175..2f4ba85a0d73 100644
> --- a/drivers/net/phy/qt2025.rs
> +++ b/drivers/net/phy/qt2025.rs
> @@ -9,7 +9,6 @@
>  //!
>  //! The QT2025 PHY integrates an Intel 8051 micro-controller.
>  
> -use kernel::c_str;
>  use kernel::error::code;
>  use kernel::firmware::Firmware;
>  use kernel::net::phy::{
> @@ -36,7 +35,7 @@
>  
>  #[vtable]
>  impl Driver for PhyQT2025 {
> -    const NAME: &'static CStr = c_str!("QT2025 10Gpbs SFP+");
> +    const NAME: &'static CStr = c"QT2025 10Gpbs SFP+";
>      const PHY_DEVICE_ID: phy::DeviceId = phy::DeviceId::new_with_exact_mask(0x0043a400);
>  
>      fn probe(dev: &mut phy::Device) -> Result<()> {
> @@ -69,7 +68,7 @@ fn probe(dev: &mut phy::Device) -> Result<()> {
>          // The micro-controller will start running from the boot ROM.
>          dev.write(C45::new(Mmd::PCS, 0xe854), 0x00c0)?;
>  
> -        let fw = Firmware::request(c_str!("qt2025-2.0.3.3.fw"), dev.as_ref())?;
> +        let fw = Firmware::request(c"qt2025-2.0.3.3.fw", dev.as_ref())?;
>          if fw.data().len() > SZ_16K + SZ_8K {
>              return Err(code::EFBIG);
>          }
> diff --git a/rust/kernel/firmware.rs b/rust/kernel/firmware.rs
> index e75db4d825ce..93e375e75ca0 100644
> --- a/rust/kernel/firmware.rs
> +++ b/rust/kernel/firmware.rs
> @@ -40,13 +40,13 @@ fn request_nowarn() -> Self {
>  /// # Examples
>  ///
>  /// ```no_run
> -/// # use kernel::{c_str, device::Device, firmware::Firmware};
> +/// # use kernel::{device::Device, firmware::Firmware};
>  ///
>  /// # fn no_run() -> Result<(), Error> {
>  /// # // SAFETY: *NOT* safe, just for the example to get an `ARef<Device>` instance
>  /// # let dev = unsafe { Device::get_device(core::ptr::null_mut()) };
>  ///
> -/// let fw = Firmware::request(c_str!("path/to/firmware.bin"), &dev)?;
> +/// let fw = Firmware::request(c"path/to/firmware.bin", &dev)?;
>  /// let blob = fw.data();
>  ///
>  /// # Ok(())
> diff --git a/rust/kernel/kunit.rs b/rust/kernel/kunit.rs
> index 9f40ea744fc2..3d812edec057 100644
> --- a/rust/kernel/kunit.rs
> +++ b/rust/kernel/kunit.rs
> @@ -56,10 +56,11 @@ macro_rules! kunit_assert {
>                  break 'out;
>              }
>  
> -            static NAME: &'static $crate::str::CStr = $crate::c_str!($name);
> -            static FILE: &'static $crate::str::CStr = $crate::c_str!($file);
> +            static NAME: &'static $crate::str::CStr = $crate::c_str_avoid_literals!($name);
> +            static FILE: &'static $crate::str::CStr = $crate::c_str_avoid_literals!($file);
>              static LINE: i32 = core::line!() as i32 - $diff;
> -            static CONDITION: &'static $crate::str::CStr = $crate::c_str!(stringify!($condition));
> +            static CONDITION: &'static $crate::str::CStr =
> +                $crate::c_str_avoid_literals!(stringify!($condition));
>  
>              // SAFETY: FFI call without safety requirements.
>              let kunit_test = unsafe { $crate::bindings::kunit_get_current_test() };
> diff --git a/rust/kernel/net/phy.rs b/rust/kernel/net/phy.rs
> index 9e410de3c3a3..5fb9b0e1c9b1 100644
> --- a/rust/kernel/net/phy.rs
> +++ b/rust/kernel/net/phy.rs
> @@ -780,7 +780,6 @@ const fn as_int(&self) -> u32 {
>  ///
>  /// ```
>  /// # mod module_phy_driver_sample {
> -/// use kernel::c_str;
>  /// use kernel::net::phy::{self, DeviceId};
>  /// use kernel::prelude::*;
>  ///
> @@ -799,7 +798,7 @@ const fn as_int(&self) -> u32 {
>  ///
>  /// #[vtable]
>  /// impl phy::Driver for PhySample {
> -///     const NAME: &'static CStr = c_str!("PhySample");
> +///     const NAME: &'static CStr = c"PhySample";
>  ///     const PHY_DEVICE_ID: phy::DeviceId = phy::DeviceId::new_with_exact_mask(0x00000001);
>  /// }
>  /// # }
> @@ -808,7 +807,6 @@ const fn as_int(&self) -> u32 {
>  /// This expands to the following code:
>  ///
>  /// ```ignore
> -/// use kernel::c_str;
>  /// use kernel::net::phy::{self, DeviceId};
>  /// use kernel::prelude::*;
>  ///
> @@ -828,7 +826,7 @@ const fn as_int(&self) -> u32 {
>  ///
>  /// #[vtable]
>  /// impl phy::Driver for PhySample {
> -///     const NAME: &'static CStr = c_str!("PhySample");
> +///     const NAME: &'static CStr = c"PhySample";
>  ///     const PHY_DEVICE_ID: phy::DeviceId = phy::DeviceId::new_with_exact_mask(0x00000001);
>  /// }
>  ///
> diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
> index 2b63cfaaa981..20d852aa8b3c 100644
> --- a/rust/kernel/str.rs
> +++ b/rust/kernel/str.rs
> @@ -190,14 +190,13 @@ pub trait CStrExt {
>      /// # Examples
>      ///
>      /// ```
> -    /// # use kernel::c_str;
>      /// # use kernel::fmt;
>      /// # use kernel::str::CString;
> -    /// let penguin = c_str!("🐧");
> +    /// let penguin = c"🐧";
>      /// let s = CString::try_from_fmt(fmt!("{}", penguin.display()))?;
>      /// assert_eq!(s.to_bytes_with_nul(), "\\xf0\\x9f\\x90\\xa7\0".as_bytes());
>      ///
> -    /// let ascii = c_str!("so \"cool\"");
> +    /// let ascii = c"so \"cool\"";
>      /// let s = CString::try_from_fmt(fmt!("{}", ascii.display()))?;
>      /// assert_eq!(s.to_bytes_with_nul(), "so \"cool\"\0".as_bytes());
>      /// # Ok::<(), kernel::error::Error>(())
> @@ -250,25 +249,37 @@ pub const fn as_char_ptr(c_str: &CStr) -> *const crate::ffi::c_char {
>      c_str.as_ptr().cast()
>  }
>  
> -/// Creates a new [`CStr`] from a string literal.
> +/// Creates a static C string wrapper at compile time.
>  ///
> -/// The string literal should not contain any `NUL` bytes.
> +/// Rust supports C string literals since Rust 1.77, and they should be used instead of this macro
> +/// where possible. This macro exists to allow static *non-literal* C strings to be created at
> +/// compile time. This is most often used in other macros.
> +///
> +/// # Panics
> +///
> +/// This macro panics if the operand contains an interior `NUL` byte.
>  ///
>  /// # Examples
>  ///
>  /// ```
> -/// # use kernel::c_str;
> +/// # use kernel::c_str_avoid_literals;
>  /// # use kernel::str::CStr;
> -/// const MY_CSTR: &CStr = c_str!("My awesome CStr!");
> +/// const MY_CSTR: &CStr = c_str_avoid_literals!(concat!(file!(), ":", line!(), ": My CStr!"));
>  /// ```
>  #[macro_export]
> -macro_rules! c_str {
> +macro_rules! c_str_avoid_literals {
> +    // NB: we could write `($str:lit) => compile_error!("use a C string literal instead");` here but
> +    // that would trigger when the literal is at the top of several macro expansions. That would be
> +    // too limiting to macro authors, so we rely on the name as a hint instead.
>      ($str:expr) => {{
> -        const S: &str = concat!($str, "\0");
> -        const C: &$crate::str::CStr = match $crate::str::CStr::from_bytes_with_nul(S.as_bytes()) {
> -            Ok(v) => v,
> -            Err(_) => panic!("string contains interior NUL"),
> -        };
> +        const S: &'static str = concat!($str, "\0");
> +        const C: &'static $crate::str::CStr =
> +            match $crate::str::CStr::from_bytes_with_nul(S.as_bytes()) {
> +                Ok(v) => v,
> +                Err(core::ffi::FromBytesWithNulError { .. }) => {
> +                    panic!("string contains interior NUL")
> +                }
> +            };
>          C
>      }};
>  }
> diff --git a/rust/kernel/sync.rs b/rust/kernel/sync.rs
> index 1eab7ebf25fd..ec7f80a924c3 100644
> --- a/rust/kernel/sync.rs
> +++ b/rust/kernel/sync.rs
> @@ -61,9 +61,9 @@ macro_rules! static_lock_class {
>  #[macro_export]
>  macro_rules! optional_name {
>      () => {
> -        $crate::c_str!(::core::concat!(::core::file!(), ":", ::core::line!()))
> +        $crate::c_str_avoid_literals!(::core::concat!(::core::file!(), ":", ::core::line!()))
>      };
>      ($name:literal) => {
> -        $crate::c_str!($name)
> +        $crate::c_str_avoid_literals!($name)
>      };
>  }
> diff --git a/rust/kernel/sync/lock/global.rs b/rust/kernel/sync/lock/global.rs
> index 4c4d60a51c1f..732dde45024b 100644
> --- a/rust/kernel/sync/lock/global.rs
> +++ b/rust/kernel/sync/lock/global.rs
> @@ -266,7 +266,8 @@ macro_rules! global_lock {
>          $pub enum $name {}
>  
>          impl $crate::sync::lock::GlobalLockBackend for $name {
> -            const NAME: &'static $crate::str::CStr = $crate::c_str!(::core::stringify!($name));
> +            const NAME: &'static $crate::str::CStr =
> +                $crate::c_str_avoid_literals!(::core::stringify!($name));
>              type Item = $valuety;
>              type Backend = $crate::global_lock_inner!(backend $kind);
>  
> 


  reply	other threads:[~2025-02-02 13:10 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-02 12:20 [PATCH v6 0/4] rust: replace kernel::str::CStr w/ core::ffi::CStr Tamir Duberstein
2025-02-02 12:20 ` [PATCH v6 1/4] rust: move BStr,CStr Display impls behind method Tamir Duberstein
2025-02-02 12:20 ` [PATCH v6 2/4] rust: replace `CStr` with `core::ffi::CStr` Tamir Duberstein
2025-02-02 12:54   ` Tamir Duberstein
2025-02-02 14:40     ` Tamir Duberstein
2025-02-02 12:20 ` [PATCH v6 3/4] rust: replace `kernel::c_str!` with C-Strings Tamir Duberstein
2025-02-02 13:10   ` Dirk Behme [this message]
2025-02-02 14:18     ` Tamir Duberstein
2025-02-02 12:20 ` [PATCH v6 4/4] rust: remove core::ffi::CStr reexport Tamir Duberstein

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=3e2cb277-a896-4575-b23b-8d9b42c87173@gmail.com \
    --to=dirk.behme@gmail.com \
    --cc=a.hindborg@kernel.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=gary@garyguo.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tamird@gmail.com \
    --cc=tmgross@umich.edu \
    --cc=vadorovsky@protonmail.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 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.