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 authored and ccope committed Feb 21, 2020
1 parent c006db6 commit 90bb239
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 12 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.12.2" # remember to update html_root_url
version = "0.13.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 @@ -231,7 +231,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 @@ -273,15 +273,15 @@ 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
#[allow(unknown_lints, bare_trait_objects)]
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 @@ -426,7 +426,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);
}
}
13 changes: 6 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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<E, K>(error: E, kind: K) -> Self
where
Self: Sized,
E: ::std::error::Error + Send + 'static,
K: Into<Self::ErrorKind>;
where Self: Sized,
E: ::std::error::Error + Send + Sync + 'static,
K: Into<Self::ErrorKind>;

/// Returns the kind of the error.
fn kind(&self) -> &Self::ErrorKind;
Expand Down Expand Up @@ -675,7 +674,7 @@ where
#[allow(unknown_lints, bare_trait_objects)]
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 @@ -692,7 +691,7 @@ impl Default for State {
impl State {
/// Creates a new State type
#[allow(unknown_lints, bare_trait_objects)]
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 {
next_error: Some(e),
Expand Down

0 comments on commit 90bb239

Please sign in to comment.