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

Commit 635aa19

Browse files
committed
Add generic parameter to some types (errors can now add trait bounds)
1 parent 8033fc2 commit 635aa19

File tree

3 files changed

+25
-21
lines changed

3 files changed

+25
-21
lines changed

src/error_chain.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,13 @@ macro_rules! error_chain_processed {
7878
pub $error_kind_name,
7979
/// Contains the error chain and the backtrace.
8080
#[doc(hidden)]
81-
pub $crate::State,
81+
pub $crate::State<Trait>,
8282
);
8383

84-
impl $crate::ChainedError for $error_name {
84+
impl $crate::ChainedError<Trait> for $error_name {
8585
type ErrorKind = $error_kind_name;
8686

87-
fn new(kind: $error_kind_name, state: $crate::State) -> $error_name {
87+
fn new(kind: $error_kind_name, state: $crate::State<Trait>) -> $error_name {
8888
$error_name(kind, state)
8989
}
9090

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: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ use std::iter::Iterator;
429429
#[cfg(feature = "backtrace")]
430430
use std::sync::Arc;
431431
use std::fmt;
432+
use std::marker::PhantomData;
432433

433434
#[cfg(feature = "backtrace")]
434435
pub use backtrace::Backtrace;
@@ -477,7 +478,7 @@ pub fn make_backtrace() -> Option<Arc<Backtrace>> {
477478

478479
/// This trait is implemented on all the errors generated by the `error_chain`
479480
/// macro.
480-
pub trait ChainedError: error::Error + Send + 'static {
481+
pub trait ChainedError<S: ?Sized>: error::Error + Send + 'static {
481482
/// Associated kind type.
482483
type ErrorKind;
483484

@@ -503,8 +504,8 @@ pub trait ChainedError: error::Error + Send + 'static {
503504
/// context of this error.
504505
///
505506
/// The full cause chain and backtrace, if present, will be printed.
506-
fn display<'a>(&'a self) -> Display<'a, Self> {
507-
Display(self)
507+
fn display<'a>(&'a self) -> Display<'a, Self, S> {
508+
Display(self, PhantomData)
508509
}
509510

510511
/// Extends the error chain with a new entry.
@@ -514,7 +515,7 @@ pub trait ChainedError: error::Error + Send + 'static {
514515

515516
/// Creates an error from its parts.
516517
#[doc(hidden)]
517-
fn new(kind: Self::ErrorKind, state: State) -> Self where Self: Sized;
518+
fn new(kind: Self::ErrorKind, state: State<S>) -> Self where Self: Sized;
518519

519520
/// Returns the first known backtrace, either from its State or from one
520521
/// of the errors from `foreign_links`.
@@ -526,10 +527,10 @@ pub trait ChainedError: error::Error + Send + 'static {
526527

527528
/// A struct which formats an error for output.
528529
#[derive(Debug)]
529-
pub struct Display<'a, T: 'a + ?Sized>(&'a T);
530+
pub struct Display<'a, T: 'a + ?Sized, S: ?Sized>(&'a T, PhantomData<S>);
530531

531-
impl<'a, T> fmt::Display for Display<'a, T>
532-
where T: ChainedError
532+
impl<'a, T, S> fmt::Display for Display<'a, T, S>
533+
where T: ChainedError<S>
533534
{
534535
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
535536
try!(writeln!(fmt, "Error: {}", self.0));
@@ -549,33 +550,35 @@ impl<'a, T> fmt::Display for Display<'a, T>
549550
/// Common state between errors.
550551
#[derive(Debug)]
551552
#[doc(hidden)]
552-
pub struct State {
553+
pub struct State<T: ?Sized> {
553554
/// Next error in the error chain.
554-
pub next_error: Option<Box<error::Error + Send>>,
555+
pub next_error: Option<Box<T>>,
555556
/// Backtrace for the current error.
556557
#[cfg(feature = "backtrace")]
557558
pub backtrace: Option<Arc<Backtrace>>,
558559
}
559560

560-
impl Default for State {
561+
impl<T> Default for State<T> {
561562
#[cfg(feature = "backtrace")]
562-
fn default() -> State {
563+
fn default() -> Self {
563564
State {
564565
next_error: None,
565566
backtrace: make_backtrace(),
566567
}
567568
}
568569

569570
#[cfg(not(feature = "backtrace"))]
570-
fn default() -> State {
571+
fn default() -> Self {
571572
State { next_error: None }
572573
}
573574
}
574575

575-
impl State {
576+
impl<T> State<T>
577+
where T: error::Error + Send + 'static
578+
{
576579
/// Creates a new State type
577580
#[cfg(feature = "backtrace")]
578-
pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
581+
pub fn new<CE: ChainedError<T>>(e: Box<T>) -> Self {
579582
let backtrace = CE::extract_backtrace(&*e).or_else(make_backtrace);
580583
State {
581584
next_error: Some(e),
@@ -585,7 +588,7 @@ impl State {
585588

586589
/// Creates a new State type
587590
#[cfg(not(feature = "backtrace"))]
588-
pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> State {
591+
pub fn new<CE: ChainedError>(e: Box<error::Error + Send>) -> Self {
589592
State { next_error: Some(e) }
590593
}
591594

0 commit comments

Comments
 (0)