Skip to content

Commit 3e661a7

Browse files
committed
autobox feature
1 parent 25f8ee6 commit 3e661a7

File tree

5 files changed

+83
-14
lines changed

5 files changed

+83
-14
lines changed

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "thiserror"
3-
version = "2.0.12"
3+
version = "2.0.13"
44
authors = ["David Tolnay <[email protected]>"]
55
categories = ["rust-patterns"]
66
description = "derive(Error)"
@@ -13,6 +13,7 @@ rust-version = "1.61"
1313

1414
[features]
1515
default = ["std"]
16+
autobox = ["std", "thiserror-impl/autobox"]
1617

1718
# Std feature enables support for formatting std::path::{Path, PathBuf}
1819
# conveniently in an error message.
@@ -28,7 +29,7 @@ default = ["std"]
2829
std = []
2930

3031
[dependencies]
31-
thiserror-impl = { version = "=2.0.12", path = "impl" }
32+
thiserror-impl = { version = "=2.0.13", path = "impl" }
3233

3334
[dev-dependencies]
3435
anyhow = "1.0.73"

impl/Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "thiserror-impl"
3-
version = "2.0.12"
3+
version = "2.0.13"
44
authors = ["David Tolnay <[email protected]>"]
55
description = "Implementation detail of the `thiserror` crate"
66
edition = "2021"
@@ -11,6 +11,10 @@ rust-version = "1.61"
1111
[lib]
1212
proc-macro = true
1313

14+
[features]
15+
default = []
16+
autobox = []
17+
1418
[dependencies]
1519
proc-macro2 = "1.0.74"
1620
quote = "1.0.35"

impl/src/expand.rs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -449,22 +449,45 @@ fn impl_enum(input: Enum) -> TokenStream {
449449
#ty::#variant #body
450450
}
451451
};
452+
452453
let from_impl = quote_spanned! {span=>
453454
#[automatically_derived]
454455
impl #impl_generics ::core::convert::From<#from> for #ty #ty_generics #where_clause {
455456
#from_function
456457
}
458+
457459
};
458-
Some(quote! {
459-
#[allow(
460-
deprecated,
461-
unused_qualifications,
462-
clippy::elidable_lifetime_names,
463-
clippy::needless_lifetimes,
464-
)]
465-
#from_impl
466-
})
467-
});
460+
461+
#[cfg(feature = "autobox")]
462+
let from_impl_for_box = quote_spanned! {span=>
463+
#[automatically_derived]
464+
impl #impl_generics ::core::convert::From<#from> for ::std::boxed::Box< #ty #ty_generics > #where_clause {
465+
fn from(#source_var: #from) -> Self {
466+
::std::boxed::Box::new(#ty::#variant #body)
467+
}
468+
}
469+
};
470+
471+
Some([quote! {
472+
#[allow(
473+
deprecated,
474+
unused_qualifications,
475+
clippy::elidable_lifetime_names,
476+
clippy::needless_lifetimes,
477+
)]
478+
#from_impl
479+
},
480+
#[cfg(feature = "autobox")]
481+
quote! {
482+
#[allow(
483+
deprecated,
484+
unused_qualifications,
485+
clippy::elidable_lifetime_names,
486+
clippy::needless_lifetimes,
487+
)]
488+
#from_impl_for_box
489+
}])
490+
}).flatten();
468491

469492
if input.generics.type_params().next().is_some() {
470493
let self_token = <Token![Self]>::default();

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@
257257
//! [`anyhow`]: https://github.com/dtolnay/anyhow
258258
259259
#![no_std]
260-
#![doc(html_root_url = "https://docs.rs/thiserror/2.0.12")]
260+
#![doc(html_root_url = "https://docs.rs/thiserror/2.0.13")]
261261
#![allow(
262262
clippy::elidable_lifetime_names,
263263
clippy::module_name_repetitions,

tests/test_autobox.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#![cfg(feature = "autobox")]
2+
3+
use thiserror::Error;
4+
5+
#[derive(Debug, Error)]
6+
#[error("not great")]
7+
struct VeryLargeError {
8+
a: [u8; 2048],
9+
}
10+
11+
impl VeryLargeError {
12+
fn new() -> Self {
13+
Self { a: [0; 2048] }
14+
}
15+
}
16+
17+
#[derive(Debug, Error)]
18+
enum ErrorEnum {
19+
#[error("bad")]
20+
Any(#[from] anyhow::Error),
21+
22+
#[error("worse")]
23+
Big(#[from] VeryLargeError),
24+
}
25+
26+
/// External code may still return large errors...
27+
fn do_something() -> Result<(), VeryLargeError> {
28+
Err(VeryLargeError::new())
29+
}
30+
31+
/// But we should be able to box them automatically!
32+
fn do_something_else() -> Result<(), Box<ErrorEnum>> {
33+
do_something()?;
34+
35+
Ok(())
36+
}
37+
38+
#[test]
39+
fn autobox() {
40+
let _ = do_something_else().unwrap_err();
41+
}

0 commit comments

Comments
 (0)