Limitations of downcast_ref
I encounter situations where unwrap_err().downcast_ref() on a miette::Result always returns None despite the correct error type being contained. The situation typically happens in tests where the error type that I'm trying to downcast to is defined in the same workspace member / package. If the error type is defined in another workspace member, then downcast_ref seems to work just fine. I'm wondering why this is the case and whether there are specific limitations that need to be considered.
My error types are typically defined as follows:
use miette::Diagnostic;
use thiserror::Error;
#[derive(Debug, Clone, PartialEq, Error, Diagnostic)]
pub enum MyError {
#[error("some error")]
#[diagnostic(code(myerror::some_error))]
SomeError,
}
And tests that I'm referring to have the following structure:
#[cfg(test)]
mod tests {
#[test]
fn test_some_error() {
assert_eq!(do_something().unwrap_err().downcast_ref(), Some(&MyError::SomeError));
}
}
where do_something() returns a miette::Result.
Do you have a full, self-contained repro of this? What rustc version? And so on I tried to repro it like this, but without luck:
#[derive(Debug, Clone, PartialEq, thiserror::Error, Diagnostic)]
pub enum MyError {
#[error("some error")]
#[diagnostic(code(myerror::some_error))]
SomeError,
}
fn bail_repro() -> miette::Result<()>
{
miette::Result::Err(MyError::SomeError.into())
}
#[test]
fn test_downcast_bug_repro() {
assert_eq!(bail_repro().unwrap_err().downcast_ref(), Some(&MyError::SomeError));
}
This is with rustc 1.91.1. I tried to come up with a minimal self-contained repro but failed. Maybe it's not some form of TypeId instability that I suspected, but rather my error type is getting wrapped somewhere (and I haven't found where that happens yet). Which brings me to another question: is it generally better practice with miette to test for the error code (using .unwrap_err().code()) instead of checking for the concrete error type? This seems to work reliably in my case.
I have no idea, I've contributed some but am not all-knowing :). Have you tried running the test in question under Miri? the downcasting I believe involves some unsafe code (I believe it's under eyreish?: https://github.com/zkat/miette/tree/df7bcfa17d9c0813286050ee245d5c3d94653f1c/src/eyreish). would be good to rule out UB.
Thanks for the suggestion. I can confirm that Miri doesn't flag any UB issues.