From 90bb239a92e0331ad4f2994a75090446316ad43c 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 | 13 ++++++------- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c1f3ad9ca..f561b414b 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "error-chain" -version = "0.12.2" # remember to update html_root_url +version = "0.13.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 838270962..d14b576e6 100755 --- a/src/error_chain.rs +++ b/src/error_chain.rs @@ -231,7 +231,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) @@ -273,7 +273,7 @@ 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) @@ -281,7 +281,7 @@ macro_rules! impl_error_chain_processed { /// Construct a chained error from another boxed error and a kind, and generates a backtrace #[allow(unknown_lints, bare_trait_objects)] - 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> { @@ -426,7 +426,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 c0f4d2301..2e044433a 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 b6bd2f278..10c3983ed 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -551,7 +551,7 @@ mod error_chain; mod quick_main; pub use quick_main::ExitCode; mod backtrace; -#[cfg(feature = "example_generated")] +#[cfg(any(test, feature = "example_generated"))] pub mod example_generated; pub use backtrace::Backtrace; #[doc(hidden)] @@ -603,10 +603,9 @@ 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, - K: Into; + where Self: Sized, + E: ::std::error::Error + Send + Sync + 'static, + K: Into; /// Returns the kind of the error. fn kind(&self) -> &Self::ErrorKind; @@ -675,7 +674,7 @@ where #[allow(unknown_lints, bare_trait_objects)] 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, } @@ -692,7 +691,7 @@ impl Default for State { impl State { /// Creates a new State type #[allow(unknown_lints, bare_trait_objects)] - pub fn new(e: Box) -> State { + pub fn new(e: Box) -> State { let backtrace = CE::extract_backtrace(&*e).unwrap_or_else(InternalBacktrace::new); State { next_error: Some(e),