`dbg!()` only requires `&T` (not `T`) to implement `Debug`.
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
This issue is to document a weirdness with the dbg!() macro, and possibly maybe decide if we want to change this behavior.
The following code compiles:
use std::fmt::{self, Debug, Formatter};
struct Thing;
// implemented on a reference
impl Debug for &Thing {
fn fmt(&self, _: &mut Formatter) -> fmt::Result {
Ok(())
}
}
fn main() {
dbg!(Thing);
}
Note that if we were to instead write println!("{:?}", Thing), then the code would not compile, since that syntax would require Thing to implement Debug.
This weirdness existed from the beginning, in RFC 2361, which contains example code with eprintln!(...., &expr). This reference is redundant, since eprintln already adds a reference, but this seemingly went unnoticed. Thus, this causes a value of type &&Thing (with a double reference) to be turned into the type &dyn Debug. The double reference seems a bit wasteful to me.
The weirdness was noticed in https://github.com/rust-lang/rust/pull/142594, and so a test was added to ensure that this didn't accidentally break. Note that, after this PR, the code now explicitly creates a &&Thing, then explicitly coerces that to &dyn Debug. Then, a reference to that is creating, making a &&dyn Debug, which is then again coerced to &dyn Debug. This in total results in a triple reference to the actual value.
This weirdness was rediscovered in https://github.com/rust-lang/rust/pull/154074#discussion_r2957799638, where the weirdness is preserved as-is.
Meta
Reproducible on the playground with version 1.96.0-nightly (2026-03-29 a25435bcf7cfc9b953d3), but the weirdness has existed since the stabilization of dbg!() in 1.32.0.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with library/std/src/macros.rs and the regression test tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-ref-impl.rs, then read RFC 2361's reference-level explanation. Determine whether the reference-level Debug behavior should remain or change, and capture the decision with appropriate test or documentation updates.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100