Skip to content
This repository was archived by the owner on Aug 16, 2021. It is now read-only.

Commit 85a6930

Browse files
committed
Add generic parameter to some types (errors can now add trait bounds)
1 parent 012c621 commit 85a6930

File tree

4 files changed

+40
-32
lines changed

4 files changed

+40
-32
lines changed

src/backtrace.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ mod imp {
4343
};
4444
ENABLED.store(enabled as usize + 1, Ordering::SeqCst);
4545
if !enabled {
46-
return InternalBacktrace { backtrace: None }
46+
return InternalBacktrace { backtrace: None };
4747
}
4848
}
4949
1 => return InternalBacktrace { backtrace: None },

src/error_chain.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,13 @@ macro_rules! impl_error_chain_processed {
8080
pub $error_kind_name,
8181
/// Contains the error chain and the backtrace.
8282
#[doc(hidden)]
83-
pub $crate::State,
83+
pub $crate::State<Trait>,
8484
);
8585

86-
impl $crate::ChainedError for $error_name {
86+
impl $crate::ChainedError<Trait> for $error_name {
8787
type ErrorKind = $error_kind_name;
8888

89-
fn new(kind: $error_kind_name, state: $crate::State) -> $error_name {
89+
fn new(kind: $error_kind_name, state: $crate::State<Trait>) -> $error_name {
9090
$error_name(kind, state)
9191
}
9292

src/example_generated.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020
//! arise frequently.
2121
2222
/// Another code generated by the macro.
23+
2324
pub mod inner {
2425
error_chain! {
2526
derive {
26-
PartialEq, Eq
27+
PartialEq
2728
}
2829
}
2930
}
@@ -40,11 +41,11 @@ error_chain! {
4041
Custom
4142
}
4243
derive {
43-
PartialEq, Eq
44+
PartialEq
4445
}
4546
}
4647

47-
fn foo<T: PartialEq + Eq>() {}
48+
fn foo<T: PartialEq>() {}
4849
fn bar() {
4950
foo::<Error>();
5051
}

src/lib.rs

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,7 @@
539539
use std::error;
540540
use std::iter::Iterator;
541541
use std::fmt;
542+
use std::marker::PhantomData;
542543

543544
#[macro_use]
544545
mod impl_error_chain_kind;
@@ -581,18 +582,21 @@ impl<'a> Iterator for Iter<'a> {
581582

582583
/// This trait is implemented on all the errors generated by the `error_chain`
583584
/// macro.
584-
pub trait ChainedError: error::Error + Send + 'static {
585+
pub trait ChainedError<S: ?Sized>: error::Error + Send + 'static {
585586
/// Associated kind type.
586587
type ErrorKind;
587588

588589
/// Constructs an error from a kind, and generates a backtrace.
589-
fn from_kind(kind: Self::ErrorKind) -> Self where Self: Sized;
590+
fn from_kind(kind: Self::ErrorKind) -> Self
591+
where
592+
Self: Sized;
590593

591594
/// Constructs a chained error from another error and a kind, and generates a backtrace.
592595
fn with_chain<E, K>(error: E, kind: K) -> Self
593-
where Self: Sized,
594-
E: ::std::error::Error + Send + 'static,
595-
K: Into<Self::ErrorKind>;
596+
where
597+
Self: Sized,
598+
E: ::std::error::Error + Send + 'static,
599+
K: Into<Self::ErrorKind>;
596600

597601
/// Returns the kind of the error.
598602
fn kind(&self) -> &Self::ErrorKind;
@@ -608,31 +612,36 @@ pub trait ChainedError: error::Error + Send + 'static {
608612
///
609613
/// The full cause chain and backtrace, if present, will be printed.
610614
fn display_chain<'a>(&'a self) -> DisplayChain<'a, Self> {
611-
DisplayChain(self)
615+
DisplayChain(self, PhantomData)
612616
}
613617

614618
/// Extends the error chain with a new entry.
615619
fn chain_err<F, EK>(self, error: F) -> Self
616-
where F: FnOnce() -> EK,
617-
EK: Into<Self::ErrorKind>;
620+
where
621+
F: FnOnce() -> EK,
622+
EK: Into<Self::ErrorKind>;
618623

619624
/// Creates an error from its parts.
620625
#[doc(hidden)]
621-
fn new(kind: Self::ErrorKind, state: State) -> Self where Self: Sized;
626+
fn new(kind: Self::ErrorKind, state: State<S>) -> Self
627+
where
628+
Self: Sized;
622629

623630
/// Returns the first known backtrace, either from its State or from one
624631
/// of the errors from `foreign_links`.
625632
#[doc(hidden)]
626633
fn extract_backtrace(e: &(error::Error + Send + 'static)) -> Option<InternalBacktrace>
627-
where Self: Sized;
634+
where
635+
Self: Sized;
628636
}
629637

630638
/// A struct which formats an error for output.
631639
#[derive(Debug)]
632-
pub struct DisplayChain<'a, T: 'a + ?Sized>(&'a T);
640+
pub struct DisplayChain<'a, T: 'a + ?Sized, S: ?Sized>(&'a T, PhantomData<S>);
633641

634-
impl<'a, T> fmt::Display for DisplayChain<'a, T>
635-
where T: ChainedError
642+
impl<'a, T, S> fmt::Display for DisplayChain<'a, T, S>
643+
where
644+
T: ChainedError<S>,
636645
{
637646
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
638647
// Keep `try!` for 1.10 support
@@ -653,37 +662,35 @@ impl<'a, T> fmt::Display for DisplayChain<'a, T>
653662
/// Common state between errors.
654663
#[derive(Debug)]
655664
#[doc(hidden)]
656-
pub struct State {
665+
pub struct State<T: ?Sized> {
657666
/// Next error in the error chain.
658-
pub next_error: Option<Box<error::Error + Send>>,
667+
pub next_error: Option<Box<T>>,
659668
/// Backtrace for the current error.
660669
pub backtrace: InternalBacktrace,
661670
}
662671

663-
impl Default for State {
664-
fn default() -> State {
672+
impl<T> Default for State<T> {
673+
#[cfg(feature = "backtrace")]
674+
fn default() -> Self {
665675
State {
666676
next_error: None,
667677
backtrace: InternalBacktrace::new(),
668678
}
669679
}
670680
}
671681

672-
impl State {
682+
impl<T> State<T>
683+
where
684+
T: error::Error + Send + 'static,
685+
{
673686
/// Creates a new State type
674687
pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
675-
let backtrace = CE::extract_backtrace(&*e)
676-
.unwrap_or_else(InternalBacktrace::new);
688+
let backtrace = CE::extract_backtrace(&*e).unwrap_or_else(InternalBacktrace::new);
677689
State {
678690
next_error: Some(e),
679691
backtrace: backtrace,
680692
}
681693
}
682-
683-
/// Returns the inner backtrace if present.
684-
pub fn backtrace(&self) -> Option<&Backtrace> {
685-
self.backtrace.as_backtrace()
686-
}
687694
}
688695

689696
/// Exits a function early with an error

0 commit comments

Comments
 (0)