Closed jnicholls closed 1 year ago
main.rs
use snafu::prelude::*;
#[derive(Debug, Snafu)]
enum Error {
Variant1 {
#[snafu(source(from(String, Into::into)))]
source: Box<dyn std::error::Error + Send + Sync>,
},
}
fn return_error() -> Result<(), String> {
Err("nope!".to_string())
}
fn demo() -> Result<(), Error> {
return_error().context(Variant1Snafu)
}
fn main() {}
Cargo.toml
[dependencies]
snafu = "=0.7.1"
snafu-derive = "=0.7.1"
Upgrading snafu-derive
to 0.7.2 causes the error
error[E0599]: no function or associated item named `generate_with_source` found for trait object `dyn GenerateImplicitData` in the current scope
--> /Users/shep/.cargo/registry/src/github.com-1ecc6299db9ec823/snafu-0.7.1/src/lib.rs:1391:17
|
1391 | #[derive(Debug, Snafu)]
| ^^^^^ function or associated item not found in `dyn GenerateImplicitData`
|
= note: this error originates in the derive macro `Snafu` (in Nightly builds, run with -Z macro-backtrace for more info)
no function or associated item named
generate_with_source
found
This occurs if you have snafu = 0.7.1
and snafu-derive = 0.7.2
, which is something I intended to work but don't have tests for. That being said...
it is now saying that
String
does not implementstd::error::Error
which is a requirement forAsErrorSource
This isn't the error I produced — can you please create a fully contained reproduction?
Sorry for not sharing it sooner. This is the message below, built against 0.7.2 of both snafu
and snafu-derive
.
error[E0599]: the method `as_error_source` exists for struct `std::string::String`, but its trait bounds were not satisfied
--> src/concatenator.rs:62:17
|
62 | #[derive(Debug, Snafu)]
| ^^^^^ method cannot be called on `std::string::String` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`std::string::String: StdError`
which is required by `std::string::String: AsErrorSource`
`str: Sized`
which is required by `str: AsErrorSource`
`str: StdError`
which is required by `str: AsErrorSource`
= note: this error originates in the derive macro `Snafu` (in Nightly builds, run with -Z macro-backtrace for more info)
This is partially my enum:
#[derive(Debug, Snafu)]
pub enum Error {
#[snafu(display("Unable to build an HDD: {source}"))]
HddBuild {
backtrace: Option<Backtrace>,
#[snafu(source(from(String, Into::into)))]
source: Box<dyn StdError + Send + Sync>,
},
}
Complete example
use snafu::{prelude::*, Backtrace};
#[derive(Debug, Snafu)]
pub struct HddBuildError {
backtrace: Option<Backtrace>,
#[snafu(source(from(String, Into::into)))]
source: Box<dyn std::error::Error + Send + Sync>,
}
fn return_error() -> Result<(), String> {
Err("nope!".to_string())
}
fn demo() -> Result<(), HddBuildError> {
return_error().context(HddBuildSnafu)
}
fn main() {}
I'll need to dig into the code, but I'm hoping that the fix here is to call the generate_with_source
method with the error after the transformation.
Yeah, we generate this:
fn into_error(self, error: Self::Source) -> HddBuildError {
HddBuildError {
backtrace: {
use ::snafu::AsErrorSource;
let error = error.as_error_source();
::snafu::GenerateImplicitData::generate_with_source(error)
},
source: (Into::into)(error),
}
}
Should need to move the (Into::into)(error)
earlier, save it as error
and pass that to generate_with_source
Great sleuthing! Thanks for jumping on this one so quickly. 🕵️
I want to clean up the commit, but can you try https://github.com/shepmaster/snafu/pull/366 locally and see if that works for your original case?
Sorry for the delay. #366 works! Thank you.
Released in 0.7.3
I had an error roughly defined as such:
In 0.7.1 this was acceptable. In 0.7.2, it is now saying that
String
does not implementstd::error::Error
which is a requirement forAsErrorSource
. I believe the derive macro is somehow using the from type as the binding for the context, which would be equivalent to trying to have asource: String
field directly, which I know has never worked.