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

Commit

Permalink
Shrink the size of all Error types
Browse files Browse the repository at this point in the history
This commit improves the in-memory size of `Error` from 7 pointers to 1 pointer.
Errors are in general relatively rare in applications and having a huge error
type ends up generating lots of instructions for moves and such, so this PR
optimizes for size and passing around errors rather than creating errors.
  • Loading branch information
alexcrichton committed Sep 23, 2017
1 parent c9b3757 commit 26e98c6
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 63 deletions.
38 changes: 0 additions & 38 deletions examples/size.rs

This file was deleted.

44 changes: 19 additions & 25 deletions src/error_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,13 @@ macro_rules! impl_error_chain_processed {
/// - a backtrace, generated when the error is created.
/// - an error chain, used for the implementation of `Error::cause()`.
#[derive(Debug)]
pub struct $error_name(
// The members must be `pub` for `links`.
/// The kind of the error.
pub $error_kind_name,
/// Contains the error chain and the backtrace.
#[doc(hidden)]
pub $crate::State,
);
pub struct $error_name(pub Box<($error_kind_name, $crate::State)>);

impl $crate::ChainedError for $error_name {
type ErrorKind = $error_kind_name;

fn new(kind: $error_kind_name, state: $crate::State) -> $error_name {
$error_name(kind, state)
$error_name(Box::new((kind, state)))
}

fn from_kind(kind: Self::ErrorKind) -> Self {
Expand Down Expand Up @@ -120,10 +113,10 @@ macro_rules! impl_error_chain_processed {
impl $error_name {
/// Constructs an error from a kind, and generates a backtrace.
pub fn from_kind(kind: $error_kind_name) -> $error_name {
$error_name(
$error_name(Box::new((
kind,
$crate::State::default(),
)
)))
}

/// Constructs a chained error from another error and a kind, and generates a backtrace.
Expand All @@ -140,15 +133,15 @@ macro_rules! impl_error_chain_processed {
-> $error_name
where K: Into<$error_kind_name>
{
$error_name(
$error_name(Box::new((
kind.into(),
$crate::State::new::<$error_name>(error, ),
)
)))
}

/// Returns the kind of the error.
pub fn kind(&self) -> &$error_kind_name {
&self.0
&(self.0).0
}

/// Iterates over the error chain.
Expand All @@ -158,7 +151,7 @@ macro_rules! impl_error_chain_processed {

/// Returns the backtrace associated with this error.
pub fn backtrace(&self) -> Option<&$crate::Backtrace> {
self.1.backtrace()
(self.0).1.backtrace()
}

/// Extends the error chain with a new entry.
Expand All @@ -170,15 +163,15 @@ macro_rules! impl_error_chain_processed {

impl ::std::error::Error for $error_name {
fn description(&self) -> &str {
self.0.description()
(self.0).0.description()
}

#[allow(unknown_lints, unused_doc_comment)]
fn cause(&self) -> Option<&::std::error::Error> {
match self.1.next_error {
match (self.0).1.next_error {
Some(ref c) => Some(&**c),
None => {
match self.0 {
match (self.0).0 {
$(
$(#[$meta_foreign_links])*
$error_kind_name::$foreign_link_variant(ref foreign_err) => {
Expand All @@ -194,18 +187,19 @@ macro_rules! impl_error_chain_processed {

impl ::std::fmt::Display for $error_name {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
::std::fmt::Display::fmt(&self.0, f)
::std::fmt::Display::fmt(&(self.0).0, f)
}
}

$(
$(#[$meta_links])*
impl From<$link_error_path> for $error_name {
fn from(e: $link_error_path) -> Self {
$error_name(
let e = *e.0;
$error_name(Box::new((
$error_kind_name::$link_variant(e.0),
e.1,
)
)))
}
}
) *
Expand Down Expand Up @@ -243,7 +237,7 @@ macro_rules! impl_error_chain_processed {
type Target = $error_kind_name;

fn deref(&self) -> &Self::Target {
&self.0
&(self.0).0
}
}

Expand Down Expand Up @@ -305,7 +299,7 @@ macro_rules! impl_error_chain_processed {

impl From<$error_name> for $error_kind_name {
fn from(e: $error_name) -> Self {
e.0
(e.0).0
}
}

Expand Down Expand Up @@ -428,13 +422,13 @@ macro_rules! impl_extract_backtrace {
fn extract_backtrace(e: &(::std::error::Error + Send + 'static))
-> Option<::std::sync::Arc<$crate::Backtrace>> {
if let Some(e) = e.downcast_ref::<$error_name>() {
return e.1.backtrace.clone();
return (e.0).1.backtrace.clone();
}
$(
$( #[$meta_links] )*
{
if let Some(e) = e.downcast_ref::<$link_error_path>() {
return e.1.backtrace.clone();
return (e.0).1.backtrace.clone();
}
}
) *
Expand Down

0 comments on commit 26e98c6

Please sign in to comment.