Skip to content

Commit f4c01b6

Browse files
committed
std: avoid tearing dbg! prints
1 parent 198328a commit f4c01b6

File tree

2 files changed

+59
-22
lines changed

2 files changed

+59
-22
lines changed

library/std/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,9 @@ extern crate std as realstd;
469469

470470
// The standard macros that are not built-in to the compiler.
471471
#[macro_use]
472-
mod macros;
472+
#[doc(hidden)]
473+
#[unstable(feature = "std_internals", issue = "none")]
474+
pub mod macros;
473475

474476
// The runtime entry point and a few unstable public functions used by the
475477
// compiler

library/std/src/macros.rs

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -347,35 +347,70 @@ macro_rules! eprintln {
347347
/// [`debug!`]: https://docs.rs/log/*/log/macro.debug.html
348348
/// [`log`]: https://crates.io/crates/log
349349
#[macro_export]
350+
#[allow_internal_unstable(std_internals)]
350351
#[cfg_attr(not(test), rustc_diagnostic_item = "dbg_macro")]
351352
#[stable(feature = "dbg_macro", since = "1.32.0")]
352353
macro_rules! dbg {
353-
// NOTE: We cannot use `concat!` to make a static string as a format argument
354-
// of `eprintln!` because `file!` could contain a `{` or
355-
// `$val` expression could be a block (`{ .. }`), in which case the `eprintln!`
356-
// will be malformed.
357354
() => {
358355
$crate::eprintln!("[{}:{}:{}]", $crate::file!(), $crate::line!(), $crate::column!())
359356
};
360-
($val:expr $(,)?) => {
357+
($($val:expr),+ $(,)?) => {
358+
$crate::macros::dbg_internal!(() () ($($val),+))
359+
};
360+
}
361+
362+
/// Internal macro that processes a list of expressions and produces a chain of
363+
/// nested `match`es, one for each expression, before finally calling `eprint!`
364+
/// with the collected information and returning all the evaluated expressions
365+
/// in a tuple.
366+
///
367+
/// E.g. `dbg_internal!(() () (1, 2))` expands into
368+
/// ```rust, ignore
369+
/// match 1 {
370+
/// tmp_1 => match 2 {
371+
/// tmp_2 => {
372+
/// eprint!("...", &tmp_1, &tmp_2, /* some other arguments */);
373+
/// (tmp_1, tmp_2)
374+
/// }
375+
/// }
376+
/// }
377+
/// ```
378+
///
379+
/// This is necessary so that `dbg!` outputs don't get torn, see #136703.
380+
#[doc(hidden)]
381+
#[rustc_macro_transparency = "semitransparent"]
382+
pub macro dbg_internal {
383+
(($($piece:literal),+) ($($processed:expr => $bound:expr),+) ()) => {{
384+
$crate::eprint!(
385+
$crate::concat!($($piece),+),
386+
$(
387+
$crate::stringify!($processed),
388+
// The `&T: Debug` check happens here (not in the format literal desugaring)
389+
// to avoid format literal related messages and suggestions.
390+
&&$bound as &dyn $crate::fmt::Debug
391+
),+,
392+
// The location returned here is that of the macro invokation, so
393+
// it will be the same for all expressions. Thus, label these
394+
// arguments so that they can be reused in every piece of the
395+
// formatting template.
396+
file=$crate::file!(),
397+
line=$crate::line!(),
398+
column=$crate::column!()
399+
);
400+
// Comma separate the variables only when necessary so that this will
401+
// not yield a tuple for a single expression, but rather just parenthesize
402+
// the expression.
403+
($($bound),+)
404+
}},
405+
(($($piece:literal),*) ($($processed:expr => $bound:expr),*) ($val:expr $(,$rest:expr)*)) => {{
361406
// Use of `match` here is intentional because it affects the lifetimes
362407
// of temporaries - https://stackoverflow.com/a/48732525/1063961
363408
match $val {
364-
tmp => {
365-
$crate::eprintln!("[{}:{}:{}] {} = {:#?}",
366-
$crate::file!(),
367-
$crate::line!(),
368-
$crate::column!(),
369-
$crate::stringify!($val),
370-
// The `&T: Debug` check happens here (not in the format literal desugaring)
371-
// to avoid format literal related messages and suggestions.
372-
&&tmp as &dyn $crate::fmt::Debug,
373-
);
374-
tmp
375-
}
409+
tmp => $crate::macros::dbg_internal!(
410+
($($piece,)* "[{file}:{line}:{column}] {} = {:#?}]\n")
411+
($($processed => $bound,)* $val => tmp)
412+
($($rest),*)
413+
),
376414
}
377-
};
378-
($($val:expr),+ $(,)?) => {
379-
($($crate::dbg!($val)),+,)
380-
};
415+
}},
381416
}

0 commit comments

Comments
 (0)