diff --git a/src/eyreish/error.rs b/src/eyreish/error.rs index 13c71c3..94e4128 100644 --- a/src/eyreish/error.rs +++ b/src/eyreish/error.rs @@ -542,7 +542,8 @@ where E: Diagnostic + Send + Sync + 'static, { // Attach ErrorImpl's native StdError vtable. The StdError impl is below. - e.cast::>().boxed() + let unerased = e.cast::>().boxed(); + Box::new(unerased._object) } // Safety: requires layout of *e to match ErrorImpl. @@ -553,7 +554,8 @@ where E: StdError + Send + Sync + 'static, { // Attach ErrorImpl's native StdError vtable. The StdError impl is below. - e.cast::>().boxed() + let unerased = e.cast::>().boxed(); + Box::new(unerased._object) } // Safety: requires layout of *e to match ErrorImpl. @@ -726,17 +728,6 @@ impl ErasedErrorImpl { } } -impl StdError for ErrorImpl -where - E: StdError, -{ - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - unsafe { ErrorImpl::diagnostic(self.erase()).source() } - } -} - -impl Diagnostic for ErrorImpl where E: Diagnostic {} - impl Debug for ErrorImpl where E: Debug, diff --git a/tests/test_boxed.rs b/tests/test_boxed.rs index d6fa6f8..9f9f4e2 100644 --- a/tests/test_boxed.rs +++ b/tests/test_boxed.rs @@ -1,6 +1,7 @@ use miette::{miette, Diagnostic, LabeledSpan, Report, SourceSpan}; use std::error::Error as StdError; use std::io; +use std::ops::Deref; use thiserror::Error; #[derive(Error, Debug)] @@ -159,7 +160,7 @@ impl Diagnostic for CustomDiagnostic { #[test] fn test_boxed_custom_diagnostic() { - fn assert_report(report: &Report) { + fn assert_report(report: &impl Deref) { assert_eq!( report.source().map(|source| source.to_string()), Some("oh no!".to_owned()), @@ -215,10 +216,16 @@ fn test_boxed_custom_diagnostic() { let main_diagnostic = Box::new(main_diagnostic) as Box; let report = miette!(main_diagnostic); assert_report(&report); + + // Now make sure that conversion to a trait-object is lossless! + let report_ref: &dyn Diagnostic = report.as_ref(); + assert_report(&report_ref); + + let report_box: Box = report.into(); + assert_report(&report_box); } #[test] -#[ignore = "I don't know why this isn't working but it needs fixing."] fn test_boxed_sources() { let error = MyError { source: io::Error::new(io::ErrorKind::Other, "oh no!"),