Conversion to Box<dyn Error> loses downcast ability
When I have an anyhow::Error and convert that into a Box<dyn std::error::Error>, it seems that I can no longer downcast it back into anything (neither anyhow::Error nor the original error type). This differs from the behavior of casting the anyhow error to a &(dyn StdError + 'static), which does still allow downcasting to the orignal type.
Perhaps this is a limitation that cannot be solved, but I couldn't find it documented so I wasn't sure if it was known.
use std::fmt;
use std::error::Error as StdError;
type BoxError = Box<dyn StdError + Send + Sync>;
#[derive(Debug)]
struct Sentinel;
impl fmt::Display for Sentinel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("sentinel")
}
}
impl StdError for Sentinel {}
let a: anyhow::Error = Sentinel.into();
let ar: &(dyn StdError + 'static) = a.as_ref();
dbg!(ar.is::<Sentinel>()); // true
let b: BoxError = a.into();
dbg!(b.is::<Sentinel>()); // false
//dbg!(b.is::<anyhow::Error>()); // can't do
Came across this myself today. I expected that I could massage the Anyhow boxed error back into an anyhow::Error but that also doesn't work.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f35fe71789ec7ac29cb0610a28ef68da
Naively, I thought the from_boxed1 could check to see if the Boxed error is an ErrorImpl, but it can't since object_boxed revives the erased type before boxing2