Open thomcc opened 2 years ago
On the other hand, perhaps this isn't worth having. In principal, enough information to figure out what type the error initially had should probably be present in the Debug output. And it may be too similar to
Error::description()
, which we deprecated -- presumably (I don't actually know the reason) for being inflexible and redundant, which are arguably flaws this would have as well. Also, the fact that I was able to capture this prior to type erasure without much pain indicates that perhaps this would be true for most other situations where it's needed.
My understanding is that description
was deprecated because it's signature was to just return a &str
, so it didn't allow for runtime context to be included without preformatting the string and holding the backing storage for the str in the error itself. If I could go back and change everything I think I'd make it so that description was fn description(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
and have Display
be a blanket impl for all error types that does the common case of printing the error and it's sources on a single line, and possibly use the alt flag to print errors on multiple lines.
(P.S. Sorry if this has been discussed, I didn't see it)
This hasn't been discussed before that I can recall, so you're good.
Is it currently possible to do this for a &dyn Any
? I made a basic attempt but was only able to get dyn Any
as the type_name. https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=3d52f1d764039ed4f50089af1f6d5f09
In my mind, the only reason Error
has any of this type erasure machinery is because it isn't possible to have compound vtables like dyn Error + Any
. I would like to preserve that equivalence as much as possible, so I wouldn't be in favor of adding this to dyn Error
unless similar functionality was adopted for dyn Any
.
Is it currently possible to do this for a &dyn Any? I made a basic attempt but was only able to get dyn Any as the type_name.
No. I suspect supporting this for dyn Any
would have a much larger cost in terms of code size than only doing it for error, although it would still be less than supporting it for all trait objects, so perhaps the cost would be low enough not to matter.
It would be nice (IMO) if there were a way to recover the type name (as produced by
core::any::type_name
[^1]) of adyn Error
. I've wanted this several times, as in many cases, it can be useful as a summary of what went wrong at a fairly high level, and without any details (since the details are available through other means, such as the Debug/Display implementations).(A concrete use case I've recently hit involves serializing
Error
instances for remote reporting, where the type name could be useful for broad categorization. That said, for my case it is not a problem to capture this information when the error is generated, before its type is erased. So... I don't know how compelling this example is)On the other hand, perhaps this isn't worth having. In principal, enough information to figure out what type the error initially had should probably be present in the Debug output. And it may be too similar to
Error::description()
, which we deprecated -- presumably (I don't actually know the reason) for being inflexible and redundant, which are arguably flaws this would have as well. Also, the fact that I was able to capture this prior to type erasure without much pain indicates that perhaps this would be true for most other situations where it's needed.If we do want it, I think it would be straightforward to implement -- I'm imagining that this would just be a
type_name(&self) -> &'static str
on the error trait, and would have an implementation similar to that ofError::type_id
. I think it would have the same non-guarantees thatcore::any::type_name
has for consistency, accuracy, etc. (Also, while I don't see a reason to allow users to override it, I don't really see a reason to forbid it either -- It's not like anybody can trust it being accurate or consistent, after all). That said, I don't feel very strongly about these implementation details -- you certainly could design it other ways (including repurposingError::description()
, although this would certainly not be my suggestion).(P.S. Sorry if this has been discussed, I didn't see it)
[^1]: Note that while
core::any::type_name_of_val
exists and seems like it would support trait objects, it doesn't (at least, not really -- it essentially just reportsdyn std::error::Error
). I believe this is intentional, and that it probably will due to the nontrivial binary size cost this would incur, even for code that doesn't use it.