Merge remote-tracking branch 'fork/master'

This commit is contained in:
Conrado Gouvea 2024-02-26 13:40:15 -03:00
commit bc3cc1d36c
46 changed files with 140 additions and 68 deletions

View File

@ -1,18 +1,18 @@
[package]
name = "thiserror"
name = "thiserror-nostd-notrait"
version = "1.0.57"
authors = ["David Tolnay <dtolnay@gmail.com>"]
categories = ["rust-patterns"]
description = "derive(Error)"
documentation = "https://docs.rs/thiserror"
documentation = "https://docs.rs/thiserror-nostd-notrait"
edition = "2021"
keywords = ["error", "error-handling", "derive"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/thiserror"
repository = "https://github.com/ZcashFoundation/thiserror-nostd-notrait"
rust-version = "1.56"
[dependencies]
thiserror-impl = { version = "=1.0.57", path = "impl" }
thiserror-impl = { version = "=1.0.57", path = "impl", default-features = false, package = "thiserror-nostd-notrait-impl" }
[dev-dependencies]
anyhow = "1.0.73"
@ -26,3 +26,7 @@ members = ["impl"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
rustdoc-args = ["--generate-link-to-definition"]
[features]
default = ["std"]
std = ["thiserror-impl/std"]

View File

@ -11,9 +11,16 @@ This library provides a convenient derive macro for the standard library's
[`std::error::Error`]: https://doc.rust-lang.org/std/error/trait.Error.html
This fork supports `no_std` by not deriving `Error` if `std` is not enabled.
This is useful if your library uses `thiserror` features like deriving `Display`
implementations, deriving errors from others and so on, but not the `Error`
trait itself. If you can be restricted to nightly Rust, use
[`https://crates.io/crates/thiserror-no-std`].
```toml
[dependencies]
thiserror = "1.0"
thiserror = { version = "1.0", package = "thiserror-nostd-notrait" }
```
*Compiler support: requires rustc 1.56+*
@ -23,7 +30,7 @@ thiserror = "1.0"
## Example
```rust
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum DataStoreError {

View File

@ -1,11 +1,11 @@
[package]
name = "thiserror-impl"
name = "thiserror-nostd-notrait-impl"
version = "1.0.57"
authors = ["David Tolnay <dtolnay@gmail.com>"]
description = "Implementation detail of the `thiserror` crate"
description = "Implementation detail of the `thiserror-nostd-notrait` crate"
edition = "2021"
license = "MIT OR Apache-2.0"
repository = "https://github.com/dtolnay/thiserror"
repository = "https://github.com/ZcashFoundation/thiserror-nostd-notrait"
rust-version = "1.56"
[lib]
@ -19,3 +19,7 @@ syn = "2.0.46"
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
rustdoc-args = ["--generate-link-to-definition"]
[features]
default = ["std"]
std = []

View File

@ -1,11 +1,17 @@
use crate::ast::{Enum, Field, Input, Struct};
use crate::attr::Trait;
use crate::generics::InferredBounds;
#[cfg(feature = "std")]
use crate::span::MemberSpan;
extern crate alloc;
use alloc::collections::BTreeSet as Set;
use proc_macro2::TokenStream;
use quote::{format_ident, quote, quote_spanned, ToTokens};
use std::collections::BTreeSet as Set;
use syn::{DeriveInput, GenericArgument, Member, PathArguments, Result, Token, Type};
#[cfg(feature = "std")]
use quote::quote_spanned;
use quote::{format_ident, quote, ToTokens};
#[cfg(feature = "std")]
use syn::Token;
use syn::{DeriveInput, GenericArgument, Member, PathArguments, Result, Type};
pub fn derive(input: &DeriveInput) -> TokenStream {
match try_expand(input) {
@ -55,8 +61,10 @@ fn fallback(input: &DeriveInput, error: syn::Error) -> TokenStream {
fn impl_struct(input: Struct) -> TokenStream {
let ty = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
#[cfg(feature = "std")]
let mut error_inferred_bounds = InferredBounds::new();
#[cfg(feature = "std")]
let source_body = if let Some(transparent_attr) = &input.attrs.transparent {
let only_field = &input.fields[0];
if only_field.contains_generic {
@ -86,15 +94,17 @@ fn impl_struct(input: Struct) -> TokenStream {
} else {
None
};
#[cfg(feature = "std")]
let source_method = source_body.map(|body| {
quote! {
fn source(&self) -> ::core::option::Option<&(dyn std::error::Error + 'static)> {
use thiserror::__private::AsDynError as _;
use thiserror_nostd_notrait::__private::AsDynError as _;
#body
}
}
});
#[cfg(feature = "std")]
let provide_method = input.backtrace_field().map(|backtrace_field| {
let request = quote!(request);
let backtrace = &backtrace_field.member;
@ -125,7 +135,7 @@ fn impl_struct(input: Struct) -> TokenStream {
})
};
quote! {
use thiserror::__private::ThiserrorProvide as _;
use thiserror_nostd_notrait::__private::ThiserrorProvide as _;
#source_provide
#self_provide
}
@ -202,13 +212,16 @@ fn impl_struct(input: Struct) -> TokenStream {
}
});
#[cfg(feature = "std")]
if input.generics.type_params().next().is_some() {
let self_token = <Token![Self]>::default();
error_inferred_bounds.insert(self_token, Trait::Debug);
error_inferred_bounds.insert(self_token, Trait::Display);
}
#[cfg(feature = "std")]
let error_where_clause = error_inferred_bounds.augment_where_clause(input.generics);
#[cfg(feature = "std")]
quote! {
#[allow(unused_qualifications)]
impl #impl_generics std::error::Error for #ty #ty_generics #error_where_clause {
@ -218,13 +231,20 @@ fn impl_struct(input: Struct) -> TokenStream {
#display_impl
#from_impl
}
#[cfg(not(feature = "std"))]
quote! {
#display_impl
#from_impl
}
}
fn impl_enum(input: Enum) -> TokenStream {
let ty = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
#[cfg(feature = "std")]
let mut error_inferred_bounds = InferredBounds::new();
#[cfg(feature = "std")]
let source_method = if input.has_source() {
let arms = input.variants.iter().map(|variant| {
let ident = &variant.ident;
@ -266,7 +286,7 @@ fn impl_enum(input: Enum) -> TokenStream {
});
Some(quote! {
fn source(&self) -> ::core::option::Option<&(dyn std::error::Error + 'static)> {
use thiserror::__private::AsDynError as _;
use thiserror_nostd_notrait::__private::AsDynError as _;
#[allow(deprecated)]
match self {
#(#arms)*
@ -277,6 +297,7 @@ fn impl_enum(input: Enum) -> TokenStream {
None
};
#[cfg(feature = "std")]
let provide_method = if input.has_backtrace() {
let request = quote!(request);
let arms = input.variants.iter().map(|variant| {
@ -316,7 +337,7 @@ fn impl_enum(input: Enum) -> TokenStream {
#source: #varsource,
..
} => {
use thiserror::__private::ThiserrorProvide as _;
use thiserror_nostd_notrait::__private::ThiserrorProvide as _;
#source_provide
#self_provide
}
@ -340,7 +361,7 @@ fn impl_enum(input: Enum) -> TokenStream {
};
quote! {
#ty::#ident {#backtrace: #varsource, ..} => {
use thiserror::__private::ThiserrorProvide as _;
use thiserror_nostd_notrait::__private::ThiserrorProvide as _;
#source_provide
}
}
@ -458,13 +479,16 @@ fn impl_enum(input: Enum) -> TokenStream {
})
});
#[cfg(feature = "std")]
if input.generics.type_params().next().is_some() {
let self_token = <Token![Self]>::default();
error_inferred_bounds.insert(self_token, Trait::Debug);
error_inferred_bounds.insert(self_token, Trait::Display);
}
#[cfg(feature = "std")]
let error_where_clause = error_inferred_bounds.augment_where_clause(input.generics);
#[cfg(feature = "std")]
quote! {
#[allow(unused_qualifications)]
impl #impl_generics std::error::Error for #ty #ty_generics #error_where_clause {
@ -474,6 +498,11 @@ fn impl_enum(input: Enum) -> TokenStream {
#display_impl
#(#from_impls)*
}
#[cfg(not(feature = "std"))]
quote! {
#display_impl
#(#from_impls)*
}
}
fn fields_pat(fields: &[Field]) -> TokenStream {
@ -494,7 +523,7 @@ fn fields_pat(fields: &[Field]) -> TokenStream {
fn use_as_display(needs_as_display: bool) -> Option<TokenStream> {
if needs_as_display {
Some(quote! {
use thiserror::__private::AsDisplay as _;
use thiserror_nostd_notrait::__private::AsDisplay as _;
})
} else {
None

View File

@ -1,13 +1,18 @@
use crate::ast::{Enum, Field, Struct, Variant};
#[cfg(feature = "std")]
use crate::span::MemberSpan;
#[cfg(feature = "std")]
use proc_macro2::Span;
use syn::{Member, Type};
#[cfg(feature = "std")]
use syn::Member;
use syn::Type;
impl Struct<'_> {
pub(crate) fn from_field(&self) -> Option<&Field> {
from_field(&self.fields)
}
#[cfg(feature = "std")]
pub(crate) fn source_field(&self) -> Option<&Field> {
source_field(&self.fields)
}
@ -23,12 +28,14 @@ impl Struct<'_> {
}
impl Enum<'_> {
#[cfg(feature = "std")]
pub(crate) fn has_source(&self) -> bool {
self.variants
.iter()
.any(|variant| variant.source_field().is_some() || variant.attrs.transparent.is_some())
}
#[cfg(feature = "std")]
pub(crate) fn has_backtrace(&self) -> bool {
self.variants
.iter()
@ -54,6 +61,7 @@ impl Variant<'_> {
from_field(&self.fields)
}
#[cfg(feature = "std")]
pub(crate) fn source_field(&self) -> Option<&Field> {
source_field(&self.fields)
}
@ -73,6 +81,7 @@ impl Field<'_> {
type_is_backtrace(self.ty)
}
#[cfg(feature = "std")]
pub(crate) fn source_span(&self) -> Span {
if let Some(source_attr) = &self.attrs.source {
source_attr.path().get_ident().unwrap().span()
@ -93,6 +102,7 @@ fn from_field<'a, 'b>(fields: &'a [Field<'b>]) -> Option<&'a Field<'b>> {
None
}
#[cfg(feature = "std")]
fn source_field<'a, 'b>(fields: &'a [Field<'b>]) -> Option<&'a Field<'b>> {
for field in fields {
if field.attrs.from.is_some() || field.attrs.source.is_some() {

View File

@ -1,4 +1,5 @@
use std::fmt::Display;
use core::fmt::Display;
#[cfg(feature = "std")]
use std::path::{self, Path, PathBuf};
#[doc(hidden)]
@ -21,6 +22,7 @@ where
}
}
#[cfg(feature = "std")]
impl<'a> AsDisplay<'a> for Path {
type Target = path::Display<'a>;
@ -30,6 +32,7 @@ impl<'a> AsDisplay<'a> for Path {
}
}
#[cfg(feature = "std")]
impl<'a> AsDisplay<'a> for PathBuf {
type Target = path::Display<'a>;

View File

@ -17,7 +17,7 @@
//!
//! ```rust
//! # use std::io;
//! use thiserror::Error;
//! use thiserror_nostd_notrait::Error;
//!
//! #[derive(Error, Debug)]
//! pub enum DataStoreError {
@ -63,7 +63,7 @@
//!
//! ```rust
//! # use std::i32;
//! # use thiserror::Error;
//! # use thiserror_nostd_notrait::Error;
//! #
//! #[derive(Error, Debug)]
//! pub enum Error {
@ -77,7 +77,7 @@
//! as `.0`.
//!
//! ```rust
//! # use thiserror::Error;
//! # use thiserror_nostd_notrait::Error;
//! #
//! # fn first_char(s: &String) -> char {
//! # s.chars().next().unwrap()
@ -130,7 +130,7 @@
//!
//! ```rust
//! # use std::fmt::{self, Display};
//! # use thiserror::Error;
//! # use thiserror_nostd_notrait::Error;
//! #
//! #[derive(Error, Debug)]
//! pub struct MyError {
@ -185,7 +185,7 @@
//! "anything else" variant.
//!
//! ```
//! # use thiserror::Error;
//! # use thiserror_nostd_notrait::Error;
//! #
//! #[derive(Error, Debug)]
//! pub enum MyError {
@ -203,7 +203,7 @@
//! able to evolve without breaking the crate's public API.
//!
//! ```
//! # use thiserror::Error;
//! # use thiserror_nostd_notrait::Error;
//! #
//! // PublicError is public, but opaque and easy to keep compatible.
//! #[derive(Error, Debug)]
@ -229,6 +229,7 @@
//! [`anyhow`]: https://github.com/dtolnay/anyhow
#![doc(html_root_url = "https://docs.rs/thiserror/1.0.57")]
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(
clippy::module_name_repetitions,
clippy::needless_lifetimes,
@ -240,9 +241,11 @@
#[cfg(all(thiserror_nightly_testing, not(error_generic_member_access)))]
compile_error!("Build script probe failed to compile.");
#[cfg(feature = "std")]
mod aserror;
mod display;
#[cfg(error_generic_member_access)]
#[cfg(feature = "std")]
mod provide;
pub use thiserror_impl::*;
@ -251,10 +254,12 @@ pub use thiserror_impl::*;
#[doc(hidden)]
pub mod __private {
#[doc(hidden)]
#[cfg(feature = "std")]
pub use crate::aserror::AsDynError;
#[doc(hidden)]
pub use crate::display::AsDisplay;
#[cfg(error_generic_member_access)]
#[doc(hidden)]
#[cfg(feature = "std")]
pub use crate::provide::ThiserrorProvide;
}

View File

@ -1,6 +1,6 @@
#![cfg_attr(thiserror_nightly_testing, feature(error_generic_member_access))]
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error("...")]
@ -19,7 +19,7 @@ pub mod structs {
use std::backtrace::Backtrace;
use std::error::{self, Error};
use std::sync::Arc;
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error("...")]
@ -153,7 +153,7 @@ pub mod enums {
use std::backtrace::Backtrace;
use std::error;
use std::sync::Arc;
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum PlainBacktrace {

View File

@ -1,6 +1,6 @@
#![deny(deprecated, clippy::all, clippy::pedantic)]
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum Error {

View File

@ -1,7 +1,7 @@
#![allow(clippy::needless_raw_string_hashes, clippy::uninlined_format_args)]
use std::fmt::{self, Display};
use thiserror::Error;
use thiserror_nostd_notrait::Error;
fn assert<T: Display>(expected: &str, value: T) {
assert_eq!(expected, value.to_string());

View File

@ -2,7 +2,7 @@
use std::fmt::{self, Display};
use std::io;
use thiserror::Error;
use thiserror_nostd_notrait::Error;
macro_rules! unimplemented_display {
($ty:ty) => {

View File

@ -1,7 +1,7 @@
#![allow(clippy::iter_cloned_collect, clippy::uninlined_format_args)]
use std::fmt::Display;
use thiserror::Error;
use thiserror_nostd_notrait::Error;
// Some of the elaborate cases from the rcc codebase, which is a C compiler in
// Rust. https://github.com/jyn514/rcc/blob/0.8.0/src/data/error.rs

View File

@ -1,7 +1,7 @@
#![allow(clippy::extra_unused_type_parameters)]
use std::io;
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error("...")]

View File

@ -1,7 +1,7 @@
#![allow(clippy::needless_late_init, clippy::uninlined_format_args)]
use std::fmt::{self, Debug, Display};
use thiserror::Error;
use thiserror_nostd_notrait::Error;
pub struct NoFormat;

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
pub use std::error::Error;

View File

@ -3,7 +3,7 @@
#[cfg(thiserror_nightly_testing)]
pub mod structs {
use std::backtrace::Backtrace;
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error("...")]
@ -48,7 +48,7 @@ pub mod structs {
#[cfg(thiserror_nightly_testing)]
pub mod enums {
use std::backtrace::Backtrace;
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum OptSourceNoBacktrace {

View File

@ -1,7 +1,9 @@
#![cfg(feature = "std")]
use ref_cast::RefCast;
use std::fmt::Display;
use std::path::{Path, PathBuf};
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error("failed to read '{file}'")]

View File

@ -1,6 +1,8 @@
#![cfg(feature = "std")]
use std::error::Error as StdError;
use std::io;
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error("implicit source")]

View File

@ -1,7 +1,8 @@
use anyhow::anyhow;
#[cfg(feature = "std")]
use std::error::Error as _;
use std::io;
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[test]
fn test_transparent_struct() {
@ -19,11 +20,13 @@ fn test_transparent_struct() {
let error = Error(ErrorKind::E0);
assert_eq!("E0", error.to_string());
#[cfg(feature = "std")]
assert!(error.source().is_none());
let io = io::Error::new(io::ErrorKind::Other, "oh no!");
let error = Error(ErrorKind::from(io));
assert_eq!("E1", error.to_string());
#[cfg(feature = "std")]
error.source().unwrap().downcast_ref::<io::Error>().unwrap();
}
@ -42,6 +45,7 @@ fn test_transparent_enum() {
let error = Error::Other(anyhow!("inner").context("outer"));
assert_eq!("outer", error.to_string());
#[cfg(feature = "std")]
assert_eq!("inner", error.source().unwrap().to_string());
}
@ -53,6 +57,7 @@ fn test_anyhow() {
let error = Any::from(anyhow!("inner").context("outer"));
assert_eq!("outer", error.to_string());
#[cfg(feature = "std")]
assert_eq!("inner", error.source().unwrap().to_string());
}
@ -74,5 +79,6 @@ fn test_non_static() {
inner: ErrorKind::Unexpected { token: "error" },
};
assert_eq!("unexpected token: \"error\"", error.to_string());
#[cfg(feature = "std")]
assert!(error.source().is_none());
}

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error(transparent)]

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
macro_rules! error_type {
($name:ident, $what:expr) => {

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum ErrorEnum {

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error("...")]

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub struct ErrorStruct {

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error(transparent)]

View File

@ -1,7 +1,7 @@
// https://github.com/dtolnay/thiserror/issues/163
use std::backtrace::Backtrace;
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error("...")]

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Debug, Error)]
pub struct Error {

View File

@ -1,5 +1,5 @@
use std::fmt::Debug;
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error("error")]

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum Error {

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Debug)]
struct NoDisplay;

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Debug)]
pub struct NotError;

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Debug)]
pub struct NotError;

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Debug)]
struct NotError;

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Debug)]
struct NotError;

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error(transparent)]

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum Error {

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum Error {

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum Error {

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum Error {

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error(transparent)]

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error(transparent)]

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error(transparent)]

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[error(transparent)]

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum Error {

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
#[source]

View File

@ -1,4 +1,4 @@
use thiserror::Error;
use thiserror_nostd_notrait::Error;
#[derive(Error)]
pub union U {