Merge tag 'mfd-next-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
[linux-block.git] / rust / kernel / std_vendor.rs
CommitLineData
bee16889
NM
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}