From f783a0e2ae7990b6527653b7732c5756feed082e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Fri, 13 May 2022 17:19:05 +0200 Subject: [PATCH] Allow using smartpointers with source_diagnostic (#169) * Add more tests for diagnostic_source * Use Borrow::borrow instead of AsRef AsRef is not reflexive, meaning that it is not implemented as &T for all T. Borrow is though, so we use that to make sure that we always get a reference that is correct, even in the presence of smart pointers. --- miette-derive/src/diagnostic_source.rs | 4 +-- tests/test_diagnostic_source_macro.rs | 45 ++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/miette-derive/src/diagnostic_source.rs b/miette-derive/src/diagnostic_source.rs index 949defe..46a8a64 100644 --- a/miette-derive/src/diagnostic_source.rs +++ b/miette-derive/src/diagnostic_source.rs @@ -59,7 +59,7 @@ impl DiagnosticSource { }; quote! { Self::#ident #display_pat => { - std::option::Option::Some(#rel.as_ref()) + std::option::Option::Some(std::borrow::Borrow::borrow(#rel)) } } }) @@ -71,7 +71,7 @@ impl DiagnosticSource { let rel = &self.0; Some(quote! { fn diagnostic_source<'a>(&'a self) -> std::option::Option<&'a dyn miette::Diagnostic> { - std::option::Option::Some(&self.#rel) + std::option::Option::Some(std::borrow::Borrow::borrow(&self.#rel)) } }) } diff --git a/tests/test_diagnostic_source_macro.rs b/tests/test_diagnostic_source_macro.rs index d7c5d2d..8af2e88 100644 --- a/tests/test_diagnostic_source_macro.rs +++ b/tests/test_diagnostic_source_macro.rs @@ -6,15 +6,56 @@ struct AnErr; #[derive(Debug, miette::Diagnostic, thiserror::Error)] #[error("TestError")] -struct TestError { +struct TestStructError { #[diagnostic_source] asdf_inner_foo: AnErr, } +#[derive(Debug, miette::Diagnostic, thiserror::Error)] +#[error("TestError")] +enum TestEnumError { + Without, + WithTuple(#[diagnostic_source] AnErr), + WithStruct { + #[diagnostic_source] + inner: AnErr, + }, +} + +#[derive(Debug, miette::Diagnostic, thiserror::Error)] +#[error("TestError")] +struct TestTupleError(#[diagnostic_source] AnErr); + +#[derive(Debug, miette::Diagnostic, thiserror::Error)] +#[error("TestError")] +struct TestBoxedError(#[diagnostic_source] Box); + +#[derive(Debug, miette::Diagnostic, thiserror::Error)] +#[error("TestError")] +struct TestArcedError(#[diagnostic_source] std::sync::Arc); + #[test] fn test_diagnostic_source() { - let error = TestError { + let error = TestStructError { asdf_inner_foo: AnErr, }; assert!(error.diagnostic_source().is_some()); + + let error = TestEnumError::Without; + assert!(error.diagnostic_source().is_none()); + + let error = TestEnumError::WithTuple(AnErr); + assert!(error.diagnostic_source().is_some()); + + let error = TestEnumError::WithStruct { inner: AnErr }; + assert!(error.diagnostic_source().is_some()); + + let error = TestTupleError(AnErr); + assert!(error.diagnostic_source().is_some()); + + let error = TestBoxedError(Box::new(AnErr)); + assert!(error.diagnostic_source().is_some()); + + let error = TestArcedError(std::sync::Arc::new(AnErr)); + assert!(error.diagnostic_source().is_some()); }