Loading...
1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3//! The contents of this file come from the Rust standard library, hosted in
4//! the <https://github.com/rust-lang/rust> repository, licensed under
5//! "Apache-2.0 OR MIT" and adapted for kernel use. For copyright details,
6//! see <https://github.com/rust-lang/rust/blob/master/COPYRIGHT>.
7
8/// [`std::dbg`], but using [`pr_info`] instead of [`eprintln`].
9///
10/// Prints and returns the value of a given expression for quick and dirty
11/// debugging.
12///
13/// An example:
14///
15/// ```rust
16/// let a = 2;
17/// # #[allow(clippy::dbg_macro)]
18/// let b = dbg!(a * 2) + 1;
19/// // ^-- prints: [src/main.rs:2] a * 2 = 4
20/// assert_eq!(b, 5);
21/// ```
22///
23/// The macro works by using the `Debug` implementation of the type of
24/// the given expression to print the value with [`printk`] along with the
25/// source location of the macro invocation as well as the source code
26/// of the expression.
27///
28/// Invoking the macro on an expression moves and takes ownership of it
29/// before returning the evaluated expression unchanged. If the type
30/// of the expression does not implement `Copy` and you don't want
31/// to give up ownership, you can instead borrow with `dbg!(&expr)`
32/// for some expression `expr`.
33///
34/// The `dbg!` macro works exactly the same in release builds.
35/// This is useful when debugging issues that only occur in release
36/// builds or when debugging in release mode is significantly faster.
37///
38/// Note that the macro is intended as a temporary debugging tool to be
39/// used during development. Therefore, avoid committing `dbg!` macro
40/// invocations into the kernel tree.
41///
42/// For debug output that is intended to be kept in the kernel tree,
43/// use [`pr_debug`] and similar facilities instead.
44///
45/// # Stability
46///
47/// The exact output printed by this macro should not be relied upon
48/// and is subject to future changes.
49///
50/// # Further examples
51///
52/// With a method call:
53///
54/// ```rust
55/// # #[allow(clippy::dbg_macro)]
56/// fn foo(n: usize) {
57/// if dbg!(n.checked_sub(4)).is_some() {
58/// // ...
59/// }
60/// }
61///
62/// foo(3)
63/// ```
64///
65/// This prints to the kernel log:
66///
67/// ```text,ignore
68/// [src/main.rs:4] n.checked_sub(4) = None
69/// ```
70///
71/// Naive factorial implementation:
72///
73/// ```rust
74/// # #[allow(clippy::dbg_macro)]
75/// # {
76/// fn factorial(n: u32) -> u32 {
77/// if dbg!(n <= 1) {
78/// dbg!(1)
79/// } else {
80/// dbg!(n * factorial(n - 1))
81/// }
82/// }
83///
84/// dbg!(factorial(4));
85/// # }
86/// ```
87///
88/// This prints to the kernel log:
89///
90/// ```text,ignore
91/// [src/main.rs:3] n <= 1 = false
92/// [src/main.rs:3] n <= 1 = false
93/// [src/main.rs:3] n <= 1 = false
94/// [src/main.rs:3] n <= 1 = true
95/// [src/main.rs:4] 1 = 1
96/// [src/main.rs:5] n * factorial(n - 1) = 2
97/// [src/main.rs:5] n * factorial(n - 1) = 6
98/// [src/main.rs:5] n * factorial(n - 1) = 24
99/// [src/main.rs:11] factorial(4) = 24
100/// ```
101///
102/// The `dbg!(..)` macro moves the input:
103///
104/// ```ignore
105/// /// A wrapper around `usize` which importantly is not Copyable.
106/// #[derive(Debug)]
107/// struct NoCopy(usize);
108///
109/// let a = NoCopy(42);
110/// let _ = dbg!(a); // <-- `a` is moved here.
111/// let _ = dbg!(a); // <-- `a` is moved again; error!
112/// ```
113///
114/// You can also use `dbg!()` without a value to just print the
115/// file and line whenever it's reached.
116///
117/// Finally, if you want to `dbg!(..)` multiple values, it will treat them as
118/// a tuple (and return it, too):
119///
120/// ```
121/// # #[allow(clippy::dbg_macro)]
122/// assert_eq!(dbg!(1usize, 2u32), (1, 2));
123/// ```
124///
125/// However, a single argument with a trailing comma will still not be treated
126/// as a tuple, following the convention of ignoring trailing commas in macro
127/// invocations. You can use a 1-tuple directly if you need one:
128///
129/// ```
130/// # #[allow(clippy::dbg_macro)]
131/// # {
132/// assert_eq!(1, dbg!(1u32,)); // trailing comma ignored
133/// assert_eq!((1,), dbg!((1u32,))); // 1-tuple
134/// # }
135/// ```
136///
137/// [`std::dbg`]: https://doc.rust-lang.org/std/macro.dbg.html
138/// [`eprintln`]: https://doc.rust-lang.org/std/macro.eprintln.html
139/// [`printk`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html
140#[macro_export]
141macro_rules! dbg {
142 // NOTE: We cannot use `concat!` to make a static string as a format argument
143 // of `pr_info!` because `file!` could contain a `{` or
144 // `$val` expression could be a block (`{ .. }`), in which case the `pr_info!`
145 // will be malformed.
146 () => {
147 $crate::pr_info!("[{}:{}]\n", ::core::file!(), ::core::line!())
148 };
149 ($val:expr $(,)?) => {
150 // Use of `match` here is intentional because it affects the lifetimes
151 // of temporaries - https://stackoverflow.com/a/48732525/1063961
152 match $val {
153 tmp => {
154 $crate::pr_info!("[{}:{}] {} = {:#?}\n",
155 ::core::file!(), ::core::line!(), ::core::stringify!($val), &tmp);
156 tmp
157 }
158 }
159 };
160 ($($val:expr),+ $(,)?) => {
161 ($($crate::dbg!($val)),+,)
162 };
163}
1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3//! Rust standard library vendored code.
4//!
5//! The contents of this file come from the Rust standard library, hosted in
6//! the <https://github.com/rust-lang/rust> repository, licensed under
7//! "Apache-2.0 OR MIT" and adapted for kernel use. For copyright details,
8//! see <https://github.com/rust-lang/rust/blob/master/COPYRIGHT>.
9
10/// [`std::dbg`], but using [`pr_info`] instead of [`eprintln`].
11///
12/// Prints and returns the value of a given expression for quick and dirty
13/// debugging.
14///
15/// An example:
16///
17/// ```rust
18/// let a = 2;
19/// # #[expect(clippy::disallowed_macros)]
20/// let b = dbg!(a * 2) + 1;
21/// // ^-- prints: [src/main.rs:3:9] a * 2 = 4
22/// assert_eq!(b, 5);
23/// ```
24///
25/// The macro works by using the `Debug` implementation of the type of
26/// the given expression to print the value with [`printk`] along with the
27/// source location of the macro invocation as well as the source code
28/// of the expression.
29///
30/// Invoking the macro on an expression moves and takes ownership of it
31/// before returning the evaluated expression unchanged. If the type
32/// of the expression does not implement `Copy` and you don't want
33/// to give up ownership, you can instead borrow with `dbg!(&expr)`
34/// for some expression `expr`.
35///
36/// The `dbg!` macro works exactly the same in release builds.
37/// This is useful when debugging issues that only occur in release
38/// builds or when debugging in release mode is significantly faster.
39///
40/// Note that the macro is intended as a temporary debugging tool to be
41/// used during development. Therefore, avoid committing `dbg!` macro
42/// invocations into the kernel tree.
43///
44/// For debug output that is intended to be kept in the kernel tree,
45/// use [`pr_debug`] and similar facilities instead.
46///
47/// # Stability
48///
49/// The exact output printed by this macro should not be relied upon
50/// and is subject to future changes.
51///
52/// # Further examples
53///
54/// With a method call:
55///
56/// ```rust
57/// # #[expect(clippy::disallowed_macros)]
58/// fn foo(n: usize) {
59/// if dbg!(n.checked_sub(4)).is_some() {
60/// // ...
61/// }
62/// }
63///
64/// foo(3)
65/// ```
66///
67/// This prints to the kernel log:
68///
69/// ```text,ignore
70/// [src/main.rs:3:8] n.checked_sub(4) = None
71/// ```
72///
73/// Naive factorial implementation:
74///
75/// ```rust
76/// # #![expect(clippy::disallowed_macros)]
77/// fn factorial(n: u32) -> u32 {
78/// if dbg!(n <= 1) {
79/// dbg!(1)
80/// } else {
81/// dbg!(n * factorial(n - 1))
82/// }
83/// }
84///
85/// dbg!(factorial(4));
86/// ```
87///
88/// This prints to the kernel log:
89///
90/// ```text,ignore
91/// [src/main.rs:3:8] n <= 1 = false
92/// [src/main.rs:3:8] n <= 1 = false
93/// [src/main.rs:3:8] n <= 1 = false
94/// [src/main.rs:3:8] n <= 1 = true
95/// [src/main.rs:4:9] 1 = 1
96/// [src/main.rs:5:9] n * factorial(n - 1) = 2
97/// [src/main.rs:5:9] n * factorial(n - 1) = 6
98/// [src/main.rs:5:9] n * factorial(n - 1) = 24
99/// [src/main.rs:11:1] factorial(4) = 24
100/// ```
101///
102/// The `dbg!(..)` macro moves the input:
103///
104/// ```ignore
105/// /// A wrapper around `usize` which importantly is not Copyable.
106/// #[derive(Debug)]
107/// struct NoCopy(usize);
108///
109/// let a = NoCopy(42);
110/// let _ = dbg!(a); // <-- `a` is moved here.
111/// let _ = dbg!(a); // <-- `a` is moved again; error!
112/// ```
113///
114/// You can also use `dbg!()` without a value to just print the
115/// file and line whenever it's reached.
116///
117/// Finally, if you want to `dbg!(..)` multiple values, it will treat them as
118/// a tuple (and return it, too):
119///
120/// ```
121/// # #![expect(clippy::disallowed_macros)]
122/// assert_eq!(dbg!(1usize, 2u32), (1, 2));
123/// ```
124///
125/// However, a single argument with a trailing comma will still not be treated
126/// as a tuple, following the convention of ignoring trailing commas in macro
127/// invocations. You can use a 1-tuple directly if you need one:
128///
129/// ```
130/// # #![expect(clippy::disallowed_macros)]
131/// assert_eq!(1, dbg!(1u32,)); // trailing comma ignored
132/// assert_eq!((1,), dbg!((1u32,))); // 1-tuple
133/// ```
134///
135/// [`std::dbg`]: https://doc.rust-lang.org/std/macro.dbg.html
136/// [`eprintln`]: https://doc.rust-lang.org/std/macro.eprintln.html
137/// [`printk`]: https://docs.kernel.org/core-api/printk-basics.html
138/// [`pr_info`]: crate::pr_info!
139/// [`pr_debug`]: crate::pr_debug!
140#[macro_export]
141macro_rules! dbg {
142 // NOTE: We cannot use `concat!` to make a static string as a format argument
143 // of `pr_info!` because `file!` could contain a `{` or
144 // `$val` expression could be a block (`{ .. }`), in which case the `pr_info!`
145 // will be malformed.
146 () => {
147 $crate::pr_info!("[{}:{}:{}]\n", ::core::file!(), ::core::line!(), ::core::column!())
148 };
149 ($val:expr $(,)?) => {
150 // Use of `match` here is intentional because it affects the lifetimes
151 // of temporaries - https://stackoverflow.com/a/48732525/1063961
152 match $val {
153 tmp => {
154 $crate::pr_info!("[{}:{}:{}] {} = {:#?}\n",
155 ::core::file!(), ::core::line!(), ::core::column!(),
156 ::core::stringify!($val), &tmp);
157 tmp
158 }
159 }
160 };
161 ($($val:expr),+ $(,)?) => {
162 ($($crate::dbg!($val)),+,)
163 };
164}