Skip to content

Commit

Permalink
Require that errors are Send/Sync/'static.
Browse files Browse the repository at this point in the history
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 rust-lang-deprecated#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.
  • Loading branch information
Without Boats committed Nov 15, 2017
1 parent 48c18a9 commit c9260c7
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 <banderson@mozilla.com>",
"Paul Colomiets <paul@colomiets.name>",
"Colin Kiegel <kiegel@gmx.de>",
Expand Down
8 changes: 4 additions & 4 deletions src/error_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ macro_rules! impl_error_chain_processed {

fn with_chain<E, K>(error: E, kind: K)
-> Self
where E: ::std::error::Error + Send + 'static,
where E: ::std::error::Error + Send + Sync + 'static,
K: Into<Self::ErrorKind>
{
Self::with_chain(error, kind)
Expand Down Expand Up @@ -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<E, K>(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<K>(error: Box<::std::error::Error + Send>, kind: K)
pub fn with_boxed_chain<K>(error: Box<::std::error::Error + Send + Sync>, kind: K)
-> $error_name
where K: Into<$error_kind_name>
{
Expand Down Expand Up @@ -320,7 +320,7 @@ macro_rules! impl_error_chain_processed {
EK: Into<$error_kind_name>;
}

impl<T, E> $result_ext_name<T> for ::std::result::Result<T, E> where E: ::std::error::Error + Send + 'static {
impl<T, E> $result_ext_name<T> for ::std::result::Result<T, E> where E: ::std::error::Error + Send + Sync + 'static {
fn chain_err<F, EK>(self, callback: F) -> ::std::result::Result<T, $error_name>
where F: FnOnce() -> EK,
EK: Into<$error_kind_name> {
Expand Down
17 changes: 17 additions & 0 deletions src/example_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,20 @@ error_chain! {
Custom
}
}

#[cfg(test)]
mod test {

use super::Error;

#[test]
fn generated_error_meets_bounds() {
fn is_sync<T: Sync>() { }
fn is_send<T: Send>() { }
fn is_static<T: 'static>() { }
is_sync::<Error>();
is_send::<Error>();
is_static::<Error>();
assert!(true);
}
}
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<E, K>(error: E, kind: K) -> Self
where Self: Sized,
E: ::std::error::Error + Send + 'static,
E: ::std::error::Error + Send + Sync + 'static,
K: Into<Self::ErrorKind>;

/// Returns the kind of the error.
Expand Down Expand Up @@ -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<Box<error::Error + Send>>,
pub next_error: Option<Box<error::Error + Send + Sync>>,
/// Backtrace for the current error.
pub backtrace: InternalBacktrace,
}
Expand All @@ -671,7 +671,7 @@ impl Default for State {

impl State {
/// Creates a new State type
pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
pub fn new<CE: ChainedError>(e: Box<error::Error + Send + Sync>) -> State {
let backtrace = CE::extract_backtrace(&*e)
.unwrap_or_else(InternalBacktrace::new);
State {
Expand Down

0 comments on commit c9260c7

Please sign in to comment.