anyhow icon indicating copy to clipboard operation
anyhow copied to clipboard

Conversion to Box<dyn Error> loses downcast ability

Open seanmonstar opened this issue 1 year ago • 1 comments

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

seanmonstar avatar Jul 05 '24 17:07 seanmonstar

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

demosdemon avatar Sep 09 '24 17:09 demosdemon