std_vendor.rs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // SPDX-License-Identifier: Apache-2.0 OR MIT
  2. //! Rust standard library vendored code.
  3. //!
  4. //! The contents of this file come from the Rust standard library, hosted in
  5. //! the <https://github.com/rust-lang/rust> repository, licensed under
  6. //! "Apache-2.0 OR MIT" and adapted for kernel use. For copyright details,
  7. //! see <https://github.com/rust-lang/rust/blob/master/COPYRIGHT>.
  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. /// # #[expect(clippy::disallowed_macros)]
  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. /// # #[expect(clippy::disallowed_macros)]
  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. /// # #[expect(clippy::disallowed_macros)]
  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. /// # #![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. /// # {
  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://docs.kernel.org/core-api/printk-basics.html
  140. /// [`pr_info`]: crate::pr_info!
  141. /// [`pr_debug`]: crate::pr_debug!
  142. #[macro_export]
  143. macro_rules! dbg {
  144. // NOTE: We cannot use `concat!` to make a static string as a format argument
  145. // of `pr_info!` because `file!` could contain a `{` or
  146. // `$val` expression could be a block (`{ .. }`), in which case the `pr_info!`
  147. // will be malformed.
  148. () => {
  149. $crate::pr_info!("[{}:{}:{}]\n", ::core::file!(), ::core::line!(), ::core::column!())
  150. };
  151. ($val:expr $(,)?) => {
  152. // Use of `match` here is intentional because it affects the lifetimes
  153. // of temporaries - https://stackoverflow.com/a/48732525/1063961
  154. match $val {
  155. tmp => {
  156. $crate::pr_info!("[{}:{}:{}] {} = {:#?}\n",
  157. ::core::file!(), ::core::line!(), ::core::column!(),
  158. ::core::stringify!($val), &tmp);
  159. tmp
  160. }
  161. }
  162. };
  163. ($($val:expr),+ $(,)?) => {
  164. ($($crate::dbg!($val)),+,)
  165. };
  166. }