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

Commit 26e98c6

Browse files
committed
Shrink the size of all Error types
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.
1 parent c9b3757 commit 26e98c6

File tree

2 files changed

+19
-63
lines changed

2 files changed

+19
-63
lines changed

examples/size.rs

Lines changed: 0 additions & 38 deletions
This file was deleted.

src/error_chain.rs

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -65,20 +65,13 @@ macro_rules! impl_error_chain_processed {
6565
/// - a backtrace, generated when the error is created.
6666
/// - an error chain, used for the implementation of `Error::cause()`.
6767
#[derive(Debug)]
68-
pub struct $error_name(
69-
// The members must be `pub` for `links`.
70-
/// The kind of the error.
71-
pub $error_kind_name,
72-
/// Contains the error chain and the backtrace.
73-
#[doc(hidden)]
74-
pub $crate::State,
75-
);
68+
pub struct $error_name(pub Box<($error_kind_name, $crate::State)>);
7669

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

8073
fn new(kind: $error_kind_name, state: $crate::State) -> $error_name {
81-
$error_name(kind, state)
74+
$error_name(Box::new((kind, state)))
8275
}
8376

8477
fn from_kind(kind: Self::ErrorKind) -> Self {
@@ -120,10 +113,10 @@ macro_rules! impl_error_chain_processed {
120113
impl $error_name {
121114
/// Constructs an error from a kind, and generates a backtrace.
122115
pub fn from_kind(kind: $error_kind_name) -> $error_name {
123-
$error_name(
116+
$error_name(Box::new((
124117
kind,
125118
$crate::State::default(),
126-
)
119+
)))
127120
}
128121

129122
/// Constructs a chained error from another error and a kind, and generates a backtrace.
@@ -140,15 +133,15 @@ macro_rules! impl_error_chain_processed {
140133
-> $error_name
141134
where K: Into<$error_kind_name>
142135
{
143-
$error_name(
136+
$error_name(Box::new((
144137
kind.into(),
145138
$crate::State::new::<$error_name>(error, ),
146-
)
139+
)))
147140
}
148141

149142
/// Returns the kind of the error.
150143
pub fn kind(&self) -> &$error_kind_name {
151-
&self.0
144+
&(self.0).0
152145
}
153146

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

159152
/// Returns the backtrace associated with this error.
160153
pub fn backtrace(&self) -> Option<&$crate::Backtrace> {
161-
self.1.backtrace()
154+
(self.0).1.backtrace()
162155
}
163156

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

171164
impl ::std::error::Error for $error_name {
172165
fn description(&self) -> &str {
173-
self.0.description()
166+
(self.0).0.description()
174167
}
175168

176169
#[allow(unknown_lints, unused_doc_comment)]
177170
fn cause(&self) -> Option<&::std::error::Error> {
178-
match self.1.next_error {
171+
match (self.0).1.next_error {
179172
Some(ref c) => Some(&**c),
180173
None => {
181-
match self.0 {
174+
match (self.0).0 {
182175
$(
183176
$(#[$meta_foreign_links])*
184177
$error_kind_name::$foreign_link_variant(ref foreign_err) => {
@@ -194,18 +187,19 @@ macro_rules! impl_error_chain_processed {
194187

195188
impl ::std::fmt::Display for $error_name {
196189
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
197-
::std::fmt::Display::fmt(&self.0, f)
190+
::std::fmt::Display::fmt(&(self.0).0, f)
198191
}
199192
}
200193

201194
$(
202195
$(#[$meta_links])*
203196
impl From<$link_error_path> for $error_name {
204197
fn from(e: $link_error_path) -> Self {
205-
$error_name(
198+
let e = *e.0;
199+
$error_name(Box::new((
206200
$error_kind_name::$link_variant(e.0),
207201
e.1,
208-
)
202+
)))
209203
}
210204
}
211205
) *
@@ -243,7 +237,7 @@ macro_rules! impl_error_chain_processed {
243237
type Target = $error_kind_name;
244238

245239
fn deref(&self) -> &Self::Target {
246-
&self.0
240+
&(self.0).0
247241
}
248242
}
249243

@@ -305,7 +299,7 @@ macro_rules! impl_error_chain_processed {
305299

306300
impl From<$error_name> for $error_kind_name {
307301
fn from(e: $error_name) -> Self {
308-
e.0
302+
(e.0).0
309303
}
310304
}
311305

@@ -428,13 +422,13 @@ macro_rules! impl_extract_backtrace {
428422
fn extract_backtrace(e: &(::std::error::Error + Send + 'static))
429423
-> Option<::std::sync::Arc<$crate::Backtrace>> {
430424
if let Some(e) = e.downcast_ref::<$error_name>() {
431-
return e.1.backtrace.clone();
425+
return (e.0).1.backtrace.clone();
432426
}
433427
$(
434428
$( #[$meta_links] )*
435429
{
436430
if let Some(e) = e.downcast_ref::<$link_error_path>() {
437-
return e.1.backtrace.clone();
431+
return (e.0).1.backtrace.clone();
438432
}
439433
}
440434
) *

0 commit comments

Comments
 (0)