From c9260c77f53b2e1c9f1bc02a0e3578425b3b18c6 Mon Sep 17 00:00:00 2001 From: Without Boats Date: Tue, 14 Nov 2017 14:57:13 -0800 Subject: [PATCH] Require that errors are Send/Sync/'static. Currently, they are not Sync because they contain a non-Sync trait object. This is a breaking change. The decision to make errors Send but not Sync was made in #110. We believe that decision was a mistake, because it perpetuates a !Sync restriction on all users even if their errors are, in fact, Sync. Instead, users who need errors that are !Sync should use synchronization when transforming their errors into error-chain errors. --- Cargo.toml | 2 +- src/error_chain.rs | 8 ++++---- src/example_generated.rs | 17 +++++++++++++++++ src/lib.rs | 8 ++++---- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 34122badb..b810ca16f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "error-chain" -version = "0.11.0" # remember to update html_root_url +version = "0.12.0" # remember to update html_root_url authors = [ "Brian Anderson ", "Paul Colomiets ", "Colin Kiegel ", diff --git a/src/error_chain.rs b/src/error_chain.rs index 9b95a77d3..34d076e8c 100644 --- a/src/error_chain.rs +++ b/src/error_chain.rs @@ -87,7 +87,7 @@ macro_rules! impl_error_chain_processed { fn with_chain(error: E, kind: K) -> Self - where E: ::std::error::Error + Send + 'static, + where E: ::std::error::Error + Send + Sync + 'static, K: Into { Self::with_chain(error, kind) @@ -129,14 +129,14 @@ macro_rules! impl_error_chain_processed { /// Constructs a chained error from another error and a kind, and generates a backtrace. pub fn with_chain(error: E, kind: K) -> $error_name - where E: ::std::error::Error + Send + 'static, + where E: ::std::error::Error + Send + Sync + 'static, K: Into<$error_kind_name> { $error_name::with_boxed_chain(Box::new(error), kind) } /// Construct a chained error from another boxed error and a kind, and generates a backtrace - pub fn with_boxed_chain(error: Box<::std::error::Error + Send>, kind: K) + pub fn with_boxed_chain(error: Box<::std::error::Error + Send + Sync>, kind: K) -> $error_name where K: Into<$error_kind_name> { @@ -320,7 +320,7 @@ macro_rules! impl_error_chain_processed { EK: Into<$error_kind_name>; } - impl $result_ext_name for ::std::result::Result where E: ::std::error::Error + Send + 'static { + impl $result_ext_name for ::std::result::Result where E: ::std::error::Error + Send + Sync + 'static { fn chain_err(self, callback: F) -> ::std::result::Result where F: FnOnce() -> EK, EK: Into<$error_kind_name> { diff --git a/src/example_generated.rs b/src/example_generated.rs index 29762eab4..65d67d2ea 100644 --- a/src/example_generated.rs +++ b/src/example_generated.rs @@ -36,3 +36,20 @@ error_chain! { Custom } } + +#[cfg(test)] +mod test { + + use super::Error; + + #[test] + fn generated_error_meets_bounds() { + fn is_sync() { } + fn is_send() { } + fn is_static() { } + is_sync::(); + is_send::(); + is_static::(); + assert!(true); + } +} diff --git a/src/lib.rs b/src/lib.rs index ac185c643..214a27faf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -547,7 +547,7 @@ mod error_chain; #[macro_use] mod quick_main; pub use quick_main::ExitCode; -#[cfg(feature = "example_generated")] +#[cfg(any(test, feature = "example_generated"))] pub mod example_generated; mod backtrace; pub use backtrace::Backtrace; @@ -591,7 +591,7 @@ pub trait ChainedError: error::Error + Send + 'static { /// Constructs a chained error from another error and a kind, and generates a backtrace. fn with_chain(error: E, kind: K) -> Self where Self: Sized, - E: ::std::error::Error + Send + 'static, + E: ::std::error::Error + Send + Sync + 'static, K: Into; /// Returns the kind of the error. @@ -655,7 +655,7 @@ impl<'a, T> fmt::Display for DisplayChain<'a, T> #[doc(hidden)] pub struct State { /// Next error in the error chain. - pub next_error: Option>, + pub next_error: Option>, /// Backtrace for the current error. pub backtrace: InternalBacktrace, } @@ -671,7 +671,7 @@ impl Default for State { impl State { /// Creates a new State type - pub fn new(e: Box) -> State { + pub fn new(e: Box) -> State { let backtrace = CE::extract_backtrace(&*e) .unwrap_or_else(InternalBacktrace::new); State {