Skip to content

Make the impl Debug for Any (+ Send) (and Box forms) more useful #1389

@abonander

Description

@abonander

Belated follow-up to the discussion on rust-lang/rust#27719

Currently, the Debug impl for Box<Any> is almost useless. It just prints "Box<Any>".

One of the main uses of Box<Any> in the stdlib is to carry the message of a panic!() invocation back to the parent, out of thread::spawn().join() or thread::catch_panic(). In this case, the Box<Any> could be one of three possibilities:

  • &'static str, if panic!() was called with a string literal and no formatting arguments.
  • String, if panic!() was called with formatting arguments.
  • Any other Send type which was passed to panic!() besides a string literal.

While the first case is technically a subset of the third, I count it as its own item because it's a common pattern when panic!() wants to give an error message but doesn't have any dynamic data to add to it.

Given the comparatively negligible overhead of downcasting, I think impl Debug for Box<Any> should test the first two cases before printing its uselessly generic message:

impl Debug for Box<Any> {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result<()>, {
        if let Ok(str_slice) = self.downcast_ref::<&'static str>() {
            fmt.pad(str_slice);
        } else if let Ok(string) = self.downcast_ref::<String>() {
            fmt.pad(string);
        } else {
            fmt.pad("Box<Any>");
        } 
    }
}

Of course, this applies to impl Debug for Any (+ Send) as well.

While this is technically a breaking change since it modifies stable behavior, I doubt anyone was relying on the exact value printed by this impl, given its completely uninformative message.

In fact, this should massively reduce the occurrence of the uninformative Thread ### panicked at Box`` message in ICE reports and StackOverflow questions. It appears this specialization is already being done: https://github.com/rust-lang/rust/blob/master/src/libstd/panicking.rs#L33

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiRelevant to the library API team, which will review and decide on the RFC.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions