-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make the impl Debug for Any (+ Send)
(and Box
forms) more useful
#1389
Comments
I'm not sure if it's a good idea to do this directly in |
@sfackler Do you have an example of a downside to this? |
It seems a bit weird to hardcode special support for exactly two types because they show up in one of |
is there a possibility to use impl specialization once we get it to add a method to |
@oli-obk You can't concatenate arbitrary traits into an object, so you could never specialize for @sfackler We could extend this to all invariant primitive types for little additional overhead (if it can be optimized down to a jump table) but that would be a lot of code bloat for arguably little benefit. I would say that If at some point we gain dynamic trait object downcasting either through some implementation detail of the type system or vtable hacking, we could remove the hardcoded solution and print all applicable types. But for now, I think something like the above is much better than a wrapper type or nothing at all. |
I meant to add a |
@cybergeek94 his suggestion was to use a wrapper to do this. pub struct Panicked(Box<Any>);
impl Debug for Panicked {
fn fmt(&self, f: &mut Formatter) -> Result {
if let Ok(str_slice) = self.0.downcast_ref::<&'static str>() {
fmt.pad(str_slice);
} else if let Ok(string) = self.0.downcast_ref::<String>() {
fmt.pad(string);
} else {
fmt.pad("Box<Any>");
}
}
} And then use the wrapper: match thread::spawn(do_work) {
Ok(..) => (),
Err(any) => println!("do_work error: {:?}", Panicked(any))
} |
That would probably be acceptable if it implemented |
I actually meant whether the following would be possible with specialization static BOX_ANY: &'static &'static str = &"Box<Any>";
pub trait Any: Reflect + 'static {
fn get_type_id(&self) -> TypeId;
fn as_debug(&self) -> &Debug {
BOX_ANY
}
}
impl<T: Debug> Any for T {
fn as_debug(&self) -> &Debug {
&self
}
}
impl Debug for Any {
fn fmt(&self, f: &mut Formatter) -> Result {
self.as_debug().fmt(f)
}
} See the error in the Playground |
I do want everyone to note that this exact thing is already being done in the panicking module, to print the panic message to stderr (I mentioned this in an edit of the original post but edits can be easy to miss): https://github.com/rust-lang/rust/blob/master/src/libstd/panicking.rs#L33 It would be nice to expose this conveniently to the user somehow, either by runtime specialization in the |
I support the special case of downcasting to Meanwhile, the problem can be solved in an ad-hoc way by extension trait impls on |
I have filed an RFC PR proposing a solution. |
Belated follow-up to the discussion on rust-lang/rust#27719
Currently, the
Debug
impl forBox<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 apanic!()
invocation back to the parent, out ofthread::spawn().join()
orthread::catch_panic()
. In this case, theBox<Any>
could be one of three possibilities:&'static str
, ifpanic!()
was called with a string literal and no formatting arguments.String
, ifpanic!()
was called with formatting arguments.Send
type which was passed topanic!()
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: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 uninformativeIt appears this specialization is already being done: https://github.com/rust-lang/rust/blob/master/src/libstd/panicking.rs#L33Thread ### panicked at
Box`` message in ICE reports and StackOverflow questions.The text was updated successfully, but these errors were encountered: