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.
This commit is contained in:
Marcel Müller 2022-05-13 17:19:05 +02:00 committed by GitHub
parent 0a4cf4ad24
commit f783a0e2ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 4 deletions

View File

@ -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))
}
})
}

View File

@ -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<dyn Diagnostic>);
#[derive(Debug, miette::Diagnostic, thiserror::Error)]
#[error("TestError")]
struct TestArcedError(#[diagnostic_source] std::sync::Arc<dyn Diagnostic>);
#[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());
}