diff options
Diffstat (limited to 'vendor/thiserror-impl/src')
-rw-r--r-- | vendor/thiserror-impl/src/ast.rs | 161 | ||||
-rw-r--r-- | vendor/thiserror-impl/src/attr.rs | 210 | ||||
-rw-r--r-- | vendor/thiserror-impl/src/expand.rs | 562 | ||||
-rw-r--r-- | vendor/thiserror-impl/src/fmt.rs | 170 | ||||
-rw-r--r-- | vendor/thiserror-impl/src/generics.rs | 83 | ||||
-rw-r--r-- | vendor/thiserror-impl/src/lib.rs | 36 | ||||
-rw-r--r-- | vendor/thiserror-impl/src/prop.rs | 147 | ||||
-rw-r--r-- | vendor/thiserror-impl/src/span.rs | 15 | ||||
-rw-r--r-- | vendor/thiserror-impl/src/valid.rs | 237 |
9 files changed, 0 insertions, 1621 deletions
diff --git a/vendor/thiserror-impl/src/ast.rs b/vendor/thiserror-impl/src/ast.rs deleted file mode 100644 index 9e06928..0000000 --- a/vendor/thiserror-impl/src/ast.rs +++ /dev/null @@ -1,161 +0,0 @@ -use crate::attr::{self, Attrs}; -use crate::generics::ParamsInScope; -use proc_macro2::Span; -use syn::{ - Data, DataEnum, DataStruct, DeriveInput, Error, Fields, Generics, Ident, Index, Member, Result, - Type, -}; - -pub enum Input<'a> { - Struct(Struct<'a>), - Enum(Enum<'a>), -} - -pub struct Struct<'a> { - pub attrs: Attrs<'a>, - pub ident: Ident, - pub generics: &'a Generics, - pub fields: Vec<Field<'a>>, -} - -pub struct Enum<'a> { - pub attrs: Attrs<'a>, - pub ident: Ident, - pub generics: &'a Generics, - pub variants: Vec<Variant<'a>>, -} - -pub struct Variant<'a> { - pub original: &'a syn::Variant, - pub attrs: Attrs<'a>, - pub ident: Ident, - pub fields: Vec<Field<'a>>, -} - -pub struct Field<'a> { - pub original: &'a syn::Field, - pub attrs: Attrs<'a>, - pub member: Member, - pub ty: &'a Type, - pub contains_generic: bool, -} - -impl<'a> Input<'a> { - pub fn from_syn(node: &'a DeriveInput) -> Result<Self> { - match &node.data { - Data::Struct(data) => Struct::from_syn(node, data).map(Input::Struct), - Data::Enum(data) => Enum::from_syn(node, data).map(Input::Enum), - Data::Union(_) => Err(Error::new_spanned( - node, - "union as errors are not supported", - )), - } - } -} - -impl<'a> Struct<'a> { - fn from_syn(node: &'a DeriveInput, data: &'a DataStruct) -> Result<Self> { - let mut attrs = attr::get(&node.attrs)?; - let scope = ParamsInScope::new(&node.generics); - let span = attrs.span().unwrap_or_else(Span::call_site); - let fields = Field::multiple_from_syn(&data.fields, &scope, span)?; - if let Some(display) = &mut attrs.display { - display.expand_shorthand(&fields); - } - Ok(Struct { - attrs, - ident: node.ident.clone(), - generics: &node.generics, - fields, - }) - } -} - -impl<'a> Enum<'a> { - fn from_syn(node: &'a DeriveInput, data: &'a DataEnum) -> Result<Self> { - let attrs = attr::get(&node.attrs)?; - let scope = ParamsInScope::new(&node.generics); - let span = attrs.span().unwrap_or_else(Span::call_site); - let variants = data - .variants - .iter() - .map(|node| { - let mut variant = Variant::from_syn(node, &scope, span)?; - if let display @ None = &mut variant.attrs.display { - *display = attrs.display.clone(); - } - if let Some(display) = &mut variant.attrs.display { - display.expand_shorthand(&variant.fields); - } else if variant.attrs.transparent.is_none() { - variant.attrs.transparent = attrs.transparent; - } - Ok(variant) - }) - .collect::<Result<_>>()?; - Ok(Enum { - attrs, - ident: node.ident.clone(), - generics: &node.generics, - variants, - }) - } -} - -impl<'a> Variant<'a> { - fn from_syn(node: &'a syn::Variant, scope: &ParamsInScope<'a>, span: Span) -> Result<Self> { - let attrs = attr::get(&node.attrs)?; - let span = attrs.span().unwrap_or(span); - Ok(Variant { - original: node, - attrs, - ident: node.ident.clone(), - fields: Field::multiple_from_syn(&node.fields, scope, span)?, - }) - } -} - -impl<'a> Field<'a> { - fn multiple_from_syn( - fields: &'a Fields, - scope: &ParamsInScope<'a>, - span: Span, - ) -> Result<Vec<Self>> { - fields - .iter() - .enumerate() - .map(|(i, field)| Field::from_syn(i, field, scope, span)) - .collect() - } - - fn from_syn( - i: usize, - node: &'a syn::Field, - scope: &ParamsInScope<'a>, - span: Span, - ) -> Result<Self> { - Ok(Field { - original: node, - attrs: attr::get(&node.attrs)?, - member: node.ident.clone().map(Member::Named).unwrap_or_else(|| { - Member::Unnamed(Index { - index: i as u32, - span, - }) - }), - ty: &node.ty, - contains_generic: scope.intersects(&node.ty), - }) - } -} - -impl Attrs<'_> { - pub fn span(&self) -> Option<Span> { - if let Some(display) = &self.display { - Some(display.fmt.span()) - } else if let Some(transparent) = &self.transparent { - Some(transparent.span) - } else { - None - } - } -} diff --git a/vendor/thiserror-impl/src/attr.rs b/vendor/thiserror-impl/src/attr.rs deleted file mode 100644 index 4beb8c9..0000000 --- a/vendor/thiserror-impl/src/attr.rs +++ /dev/null @@ -1,210 +0,0 @@ -use proc_macro2::{Delimiter, Group, Span, TokenStream, TokenTree}; -use quote::{format_ident, quote, ToTokens}; -use std::collections::BTreeSet as Set; -use syn::parse::ParseStream; -use syn::{ - braced, bracketed, parenthesized, token, Attribute, Error, Ident, Index, LitInt, LitStr, Meta, - Result, Token, -}; - -pub struct Attrs<'a> { - pub display: Option<Display<'a>>, - pub source: Option<&'a Attribute>, - pub backtrace: Option<&'a Attribute>, - pub from: Option<&'a Attribute>, - pub transparent: Option<Transparent<'a>>, -} - -#[derive(Clone)] -pub struct Display<'a> { - pub original: &'a Attribute, - pub fmt: LitStr, - pub args: TokenStream, - pub has_bonus_display: bool, - pub implied_bounds: Set<(usize, Trait)>, -} - -#[derive(Copy, Clone)] -pub struct Transparent<'a> { - pub original: &'a Attribute, - pub span: Span, -} - -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)] -pub enum Trait { - Debug, - Display, - Octal, - LowerHex, - UpperHex, - Pointer, - Binary, - LowerExp, - UpperExp, -} - -pub fn get(input: &[Attribute]) -> Result<Attrs> { - let mut attrs = Attrs { - display: None, - source: None, - backtrace: None, - from: None, - transparent: None, - }; - - for attr in input { - if attr.path().is_ident("error") { - parse_error_attribute(&mut attrs, attr)?; - } else if attr.path().is_ident("source") { - attr.meta.require_path_only()?; - if attrs.source.is_some() { - return Err(Error::new_spanned(attr, "duplicate #[source] attribute")); - } - attrs.source = Some(attr); - } else if attr.path().is_ident("backtrace") { - attr.meta.require_path_only()?; - if attrs.backtrace.is_some() { - return Err(Error::new_spanned(attr, "duplicate #[backtrace] attribute")); - } - attrs.backtrace = Some(attr); - } else if attr.path().is_ident("from") { - match attr.meta { - Meta::Path(_) => {} - Meta::List(_) | Meta::NameValue(_) => { - // Assume this is meant for derive_more crate or something. - continue; - } - } - if attrs.from.is_some() { - return Err(Error::new_spanned(attr, "duplicate #[from] attribute")); - } - attrs.from = Some(attr); - } - } - - Ok(attrs) -} - -fn parse_error_attribute<'a>(attrs: &mut Attrs<'a>, attr: &'a Attribute) -> Result<()> { - syn::custom_keyword!(transparent); - - attr.parse_args_with(|input: ParseStream| { - if let Some(kw) = input.parse::<Option<transparent>>()? { - if attrs.transparent.is_some() { - return Err(Error::new_spanned( - attr, - "duplicate #[error(transparent)] attribute", - )); - } - attrs.transparent = Some(Transparent { - original: attr, - span: kw.span, - }); - return Ok(()); - } - - let display = Display { - original: attr, - fmt: input.parse()?, - args: parse_token_expr(input, false)?, - has_bonus_display: false, - implied_bounds: Set::new(), - }; - if attrs.display.is_some() { - return Err(Error::new_spanned( - attr, - "only one #[error(...)] attribute is allowed", - )); - } - attrs.display = Some(display); - Ok(()) - }) -} - -fn parse_token_expr(input: ParseStream, mut begin_expr: bool) -> Result<TokenStream> { - let mut tokens = Vec::new(); - while !input.is_empty() { - if begin_expr && input.peek(Token![.]) { - if input.peek2(Ident) { - input.parse::<Token![.]>()?; - begin_expr = false; - continue; - } - if input.peek2(LitInt) { - input.parse::<Token![.]>()?; - let int: Index = input.parse()?; - let ident = format_ident!("_{}", int.index, span = int.span); - tokens.push(TokenTree::Ident(ident)); - begin_expr = false; - continue; - } - } - - begin_expr = input.peek(Token![break]) - || input.peek(Token![continue]) - || input.peek(Token![if]) - || input.peek(Token![in]) - || input.peek(Token![match]) - || input.peek(Token![mut]) - || input.peek(Token![return]) - || input.peek(Token![while]) - || input.peek(Token![+]) - || input.peek(Token![&]) - || input.peek(Token![!]) - || input.peek(Token![^]) - || input.peek(Token![,]) - || input.peek(Token![/]) - || input.peek(Token![=]) - || input.peek(Token![>]) - || input.peek(Token![<]) - || input.peek(Token![|]) - || input.peek(Token![%]) - || input.peek(Token![;]) - || input.peek(Token![*]) - || input.peek(Token![-]); - - let token: TokenTree = if input.peek(token::Paren) { - let content; - let delimiter = parenthesized!(content in input); - let nested = parse_token_expr(&content, true)?; - let mut group = Group::new(Delimiter::Parenthesis, nested); - group.set_span(delimiter.span.join()); - TokenTree::Group(group) - } else if input.peek(token::Brace) { - let content; - let delimiter = braced!(content in input); - let nested = parse_token_expr(&content, true)?; - let mut group = Group::new(Delimiter::Brace, nested); - group.set_span(delimiter.span.join()); - TokenTree::Group(group) - } else if input.peek(token::Bracket) { - let content; - let delimiter = bracketed!(content in input); - let nested = parse_token_expr(&content, true)?; - let mut group = Group::new(Delimiter::Bracket, nested); - group.set_span(delimiter.span.join()); - TokenTree::Group(group) - } else { - input.parse()? - }; - tokens.push(token); - } - Ok(TokenStream::from_iter(tokens)) -} - -impl ToTokens for Display<'_> { - fn to_tokens(&self, tokens: &mut TokenStream) { - let fmt = &self.fmt; - let args = &self.args; - tokens.extend(quote! { - ::core::write!(__formatter, #fmt #args) - }); - } -} - -impl ToTokens for Trait { - fn to_tokens(&self, tokens: &mut TokenStream) { - let trait_name = format_ident!("{}", format!("{:?}", self)); - tokens.extend(quote!(::core::fmt::#trait_name)); - } -} diff --git a/vendor/thiserror-impl/src/expand.rs b/vendor/thiserror-impl/src/expand.rs deleted file mode 100644 index 1b44513..0000000 --- a/vendor/thiserror-impl/src/expand.rs +++ /dev/null @@ -1,562 +0,0 @@ -use crate::ast::{Enum, Field, Input, Struct}; -use crate::attr::Trait; -use crate::generics::InferredBounds; -use crate::span::MemberSpan; -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}; - -pub fn derive(input: &DeriveInput) -> TokenStream { - match try_expand(input) { - Ok(expanded) => expanded, - // If there are invalid attributes in the input, expand to an Error impl - // anyway to minimize spurious knock-on errors in other code that uses - // this type as an Error. - Err(error) => fallback(input, error), - } -} - -fn try_expand(input: &DeriveInput) -> Result<TokenStream> { - let input = Input::from_syn(input)?; - input.validate()?; - Ok(match input { - Input::Struct(input) => impl_struct(input), - Input::Enum(input) => impl_enum(input), - }) -} - -fn fallback(input: &DeriveInput, error: syn::Error) -> TokenStream { - let ty = &input.ident; - let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - - let error = error.to_compile_error(); - - quote! { - #error - - #[allow(unused_qualifications)] - impl #impl_generics std::error::Error for #ty #ty_generics #where_clause - where - // Work around trivial bounds being unstable. - // https://github.com/rust-lang/rust/issues/48214 - for<'workaround> #ty #ty_generics: ::core::fmt::Debug, - {} - - #[allow(unused_qualifications)] - impl #impl_generics ::core::fmt::Display for #ty #ty_generics #where_clause { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - ::core::unreachable!() - } - } - } -} - -fn impl_struct(input: Struct) -> TokenStream { - let ty = &input.ident; - let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); - let mut error_inferred_bounds = InferredBounds::new(); - - let source_body = if let Some(transparent_attr) = &input.attrs.transparent { - let only_field = &input.fields[0]; - if only_field.contains_generic { - error_inferred_bounds.insert(only_field.ty, quote!(std::error::Error)); - } - let member = &only_field.member; - Some(quote_spanned! {transparent_attr.span=> - std::error::Error::source(self.#member.as_dyn_error()) - }) - } else if let Some(source_field) = input.source_field() { - let source = &source_field.member; - if source_field.contains_generic { - let ty = unoptional_type(source_field.ty); - error_inferred_bounds.insert(ty, quote!(std::error::Error + 'static)); - } - let asref = if type_is_option(source_field.ty) { - Some(quote_spanned!(source.member_span()=> .as_ref()?)) - } else { - None - }; - let dyn_error = quote_spanned! {source_field.source_span()=> - self.#source #asref.as_dyn_error() - }; - Some(quote! { - ::core::option::Option::Some(#dyn_error) - }) - } else { - None - }; - let source_method = source_body.map(|body| { - quote! { - fn source(&self) -> ::core::option::Option<&(dyn std::error::Error + 'static)> { - use thiserror::__private::AsDynError as _; - #body - } - } - }); - - let provide_method = input.backtrace_field().map(|backtrace_field| { - let request = quote!(request); - let backtrace = &backtrace_field.member; - let body = if let Some(source_field) = input.source_field() { - let source = &source_field.member; - let source_provide = if type_is_option(source_field.ty) { - quote_spanned! {source.member_span()=> - if let ::core::option::Option::Some(source) = &self.#source { - source.thiserror_provide(#request); - } - } - } else { - quote_spanned! {source.member_span()=> - self.#source.thiserror_provide(#request); - } - }; - let self_provide = if source == backtrace { - None - } else if type_is_option(backtrace_field.ty) { - Some(quote! { - if let ::core::option::Option::Some(backtrace) = &self.#backtrace { - #request.provide_ref::<std::backtrace::Backtrace>(backtrace); - } - }) - } else { - Some(quote! { - #request.provide_ref::<std::backtrace::Backtrace>(&self.#backtrace); - }) - }; - quote! { - use thiserror::__private::ThiserrorProvide as _; - #source_provide - #self_provide - } - } else if type_is_option(backtrace_field.ty) { - quote! { - if let ::core::option::Option::Some(backtrace) = &self.#backtrace { - #request.provide_ref::<std::backtrace::Backtrace>(backtrace); - } - } - } else { - quote! { - #request.provide_ref::<std::backtrace::Backtrace>(&self.#backtrace); - } - }; - quote! { - fn provide<'_request>(&'_request self, #request: &mut std::error::Request<'_request>) { - #body - } - } - }); - - let mut display_implied_bounds = Set::new(); - let display_body = if input.attrs.transparent.is_some() { - let only_field = &input.fields[0].member; - display_implied_bounds.insert((0, Trait::Display)); - Some(quote! { - ::core::fmt::Display::fmt(&self.#only_field, __formatter) - }) - } else if let Some(display) = &input.attrs.display { - display_implied_bounds = display.implied_bounds.clone(); - let use_as_display = use_as_display(display.has_bonus_display); - let pat = fields_pat(&input.fields); - Some(quote! { - #use_as_display - #[allow(unused_variables, deprecated)] - let Self #pat = self; - #display - }) - } else { - None - }; - let display_impl = display_body.map(|body| { - let mut display_inferred_bounds = InferredBounds::new(); - for (field, bound) in display_implied_bounds { - let field = &input.fields[field]; - if field.contains_generic { - display_inferred_bounds.insert(field.ty, bound); - } - } - let display_where_clause = display_inferred_bounds.augment_where_clause(input.generics); - quote! { - #[allow(unused_qualifications)] - impl #impl_generics ::core::fmt::Display for #ty #ty_generics #display_where_clause { - #[allow(clippy::used_underscore_binding)] - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #body - } - } - } - }); - - let from_impl = input.from_field().map(|from_field| { - let backtrace_field = input.distinct_backtrace_field(); - let from = unoptional_type(from_field.ty); - let body = from_initializer(from_field, backtrace_field); - quote! { - #[allow(unused_qualifications)] - impl #impl_generics ::core::convert::From<#from> for #ty #ty_generics #where_clause { - #[allow(deprecated)] - fn from(source: #from) -> Self { - #ty #body - } - } - } - }); - - 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); - } - let error_where_clause = error_inferred_bounds.augment_where_clause(input.generics); - - quote! { - #[allow(unused_qualifications)] - impl #impl_generics std::error::Error for #ty #ty_generics #error_where_clause { - #source_method - #provide_method - } - #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(); - let mut error_inferred_bounds = InferredBounds::new(); - - let source_method = if input.has_source() { - let arms = input.variants.iter().map(|variant| { - let ident = &variant.ident; - if let Some(transparent_attr) = &variant.attrs.transparent { - let only_field = &variant.fields[0]; - if only_field.contains_generic { - error_inferred_bounds.insert(only_field.ty, quote!(std::error::Error)); - } - let member = &only_field.member; - let source = quote_spanned! {transparent_attr.span=> - std::error::Error::source(transparent.as_dyn_error()) - }; - quote! { - #ty::#ident {#member: transparent} => #source, - } - } else if let Some(source_field) = variant.source_field() { - let source = &source_field.member; - if source_field.contains_generic { - let ty = unoptional_type(source_field.ty); - error_inferred_bounds.insert(ty, quote!(std::error::Error + 'static)); - } - let asref = if type_is_option(source_field.ty) { - Some(quote_spanned!(source.member_span()=> .as_ref()?)) - } else { - None - }; - let varsource = quote!(source); - let dyn_error = quote_spanned! {source_field.source_span()=> - #varsource #asref.as_dyn_error() - }; - quote! { - #ty::#ident {#source: #varsource, ..} => ::core::option::Option::Some(#dyn_error), - } - } else { - quote! { - #ty::#ident {..} => ::core::option::Option::None, - } - } - }); - Some(quote! { - fn source(&self) -> ::core::option::Option<&(dyn std::error::Error + 'static)> { - use thiserror::__private::AsDynError as _; - #[allow(deprecated)] - match self { - #(#arms)* - } - } - }) - } else { - None - }; - - let provide_method = if input.has_backtrace() { - let request = quote!(request); - let arms = input.variants.iter().map(|variant| { - let ident = &variant.ident; - match (variant.backtrace_field(), variant.source_field()) { - (Some(backtrace_field), Some(source_field)) - if backtrace_field.attrs.backtrace.is_none() => - { - let backtrace = &backtrace_field.member; - let source = &source_field.member; - let varsource = quote!(source); - let source_provide = if type_is_option(source_field.ty) { - quote_spanned! {source.member_span()=> - if let ::core::option::Option::Some(source) = #varsource { - source.thiserror_provide(#request); - } - } - } else { - quote_spanned! {source.member_span()=> - #varsource.thiserror_provide(#request); - } - }; - let self_provide = if type_is_option(backtrace_field.ty) { - quote! { - if let ::core::option::Option::Some(backtrace) = backtrace { - #request.provide_ref::<std::backtrace::Backtrace>(backtrace); - } - } - } else { - quote! { - #request.provide_ref::<std::backtrace::Backtrace>(backtrace); - } - }; - quote! { - #ty::#ident { - #backtrace: backtrace, - #source: #varsource, - .. - } => { - use thiserror::__private::ThiserrorProvide as _; - #source_provide - #self_provide - } - } - } - (Some(backtrace_field), Some(source_field)) - if backtrace_field.member == source_field.member => - { - let backtrace = &backtrace_field.member; - let varsource = quote!(source); - let source_provide = if type_is_option(source_field.ty) { - quote_spanned! {backtrace.member_span()=> - if let ::core::option::Option::Some(source) = #varsource { - source.thiserror_provide(#request); - } - } - } else { - quote_spanned! {backtrace.member_span()=> - #varsource.thiserror_provide(#request); - } - }; - quote! { - #ty::#ident {#backtrace: #varsource, ..} => { - use thiserror::__private::ThiserrorProvide as _; - #source_provide - } - } - } - (Some(backtrace_field), _) => { - let backtrace = &backtrace_field.member; - let body = if type_is_option(backtrace_field.ty) { - quote! { - if let ::core::option::Option::Some(backtrace) = backtrace { - #request.provide_ref::<std::backtrace::Backtrace>(backtrace); - } - } - } else { - quote! { - #request.provide_ref::<std::backtrace::Backtrace>(backtrace); - } - }; - quote! { - #ty::#ident {#backtrace: backtrace, ..} => { - #body - } - } - } - (None, _) => quote! { - #ty::#ident {..} => {} - }, - } - }); - Some(quote! { - fn provide<'_request>(&'_request self, #request: &mut std::error::Request<'_request>) { - #[allow(deprecated)] - match self { - #(#arms)* - } - } - }) - } else { - None - }; - - let display_impl = if input.has_display() { - let mut display_inferred_bounds = InferredBounds::new(); - let has_bonus_display = input.variants.iter().any(|v| { - v.attrs - .display - .as_ref() - .map_or(false, |display| display.has_bonus_display) - }); - let use_as_display = use_as_display(has_bonus_display); - let void_deref = if input.variants.is_empty() { - Some(quote!(*)) - } else { - None - }; - let arms = input.variants.iter().map(|variant| { - let mut display_implied_bounds = Set::new(); - let display = match &variant.attrs.display { - Some(display) => { - display_implied_bounds = display.implied_bounds.clone(); - display.to_token_stream() - } - None => { - let only_field = match &variant.fields[0].member { - Member::Named(ident) => ident.clone(), - Member::Unnamed(index) => format_ident!("_{}", index), - }; - display_implied_bounds.insert((0, Trait::Display)); - quote!(::core::fmt::Display::fmt(#only_field, __formatter)) - } - }; - for (field, bound) in display_implied_bounds { - let field = &variant.fields[field]; - if field.contains_generic { - display_inferred_bounds.insert(field.ty, bound); - } - } - let ident = &variant.ident; - let pat = fields_pat(&variant.fields); - quote! { - #ty::#ident #pat => #display - } - }); - let arms = arms.collect::<Vec<_>>(); - let display_where_clause = display_inferred_bounds.augment_where_clause(input.generics); - Some(quote! { - #[allow(unused_qualifications)] - impl #impl_generics ::core::fmt::Display for #ty #ty_generics #display_where_clause { - fn fmt(&self, __formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - #use_as_display - #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] - match #void_deref self { - #(#arms,)* - } - } - } - }) - } else { - None - }; - - let from_impls = input.variants.iter().filter_map(|variant| { - let from_field = variant.from_field()?; - let backtrace_field = variant.distinct_backtrace_field(); - let variant = &variant.ident; - let from = unoptional_type(from_field.ty); - let body = from_initializer(from_field, backtrace_field); - Some(quote! { - #[allow(unused_qualifications)] - impl #impl_generics ::core::convert::From<#from> for #ty #ty_generics #where_clause { - #[allow(deprecated)] - fn from(source: #from) -> Self { - #ty::#variant #body - } - } - }) - }); - - 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); - } - let error_where_clause = error_inferred_bounds.augment_where_clause(input.generics); - - quote! { - #[allow(unused_qualifications)] - impl #impl_generics std::error::Error for #ty #ty_generics #error_where_clause { - #source_method - #provide_method - } - #display_impl - #(#from_impls)* - } -} - -fn fields_pat(fields: &[Field]) -> TokenStream { - let mut members = fields.iter().map(|field| &field.member).peekable(); - match members.peek() { - Some(Member::Named(_)) => quote!({ #(#members),* }), - Some(Member::Unnamed(_)) => { - let vars = members.map(|member| match member { - Member::Unnamed(member) => format_ident!("_{}", member), - Member::Named(_) => unreachable!(), - }); - quote!((#(#vars),*)) - } - None => quote!({}), - } -} - -fn use_as_display(needs_as_display: bool) -> Option<TokenStream> { - if needs_as_display { - Some(quote! { - use thiserror::__private::AsDisplay as _; - }) - } else { - None - } -} - -fn from_initializer(from_field: &Field, backtrace_field: Option<&Field>) -> TokenStream { - let from_member = &from_field.member; - let some_source = if type_is_option(from_field.ty) { - quote!(::core::option::Option::Some(source)) - } else { - quote!(source) - }; - let backtrace = backtrace_field.map(|backtrace_field| { - let backtrace_member = &backtrace_field.member; - if type_is_option(backtrace_field.ty) { - quote! { - #backtrace_member: ::core::option::Option::Some(std::backtrace::Backtrace::capture()), - } - } else { - quote! { - #backtrace_member: ::core::convert::From::from(std::backtrace::Backtrace::capture()), - } - } - }); - quote!({ - #from_member: #some_source, - #backtrace - }) -} - -fn type_is_option(ty: &Type) -> bool { - type_parameter_of_option(ty).is_some() -} - -fn unoptional_type(ty: &Type) -> TokenStream { - let unoptional = type_parameter_of_option(ty).unwrap_or(ty); - quote!(#unoptional) -} - -fn type_parameter_of_option(ty: &Type) -> Option<&Type> { - let path = match ty { - Type::Path(ty) => &ty.path, - _ => return None, - }; - - let last = path.segments.last().unwrap(); - if last.ident != "Option" { - return None; - } - - let bracketed = match &last.arguments { - PathArguments::AngleBracketed(bracketed) => bracketed, - _ => return None, - }; - - if bracketed.args.len() != 1 { - return None; - } - - match &bracketed.args[0] { - GenericArgument::Type(arg) => Some(arg), - _ => None, - } -} diff --git a/vendor/thiserror-impl/src/fmt.rs b/vendor/thiserror-impl/src/fmt.rs deleted file mode 100644 index 807dfb9..0000000 --- a/vendor/thiserror-impl/src/fmt.rs +++ /dev/null @@ -1,170 +0,0 @@ -use crate::ast::Field; -use crate::attr::{Display, Trait}; -use proc_macro2::TokenTree; -use quote::{format_ident, quote_spanned}; -use std::collections::{BTreeSet as Set, HashMap as Map}; -use syn::ext::IdentExt; -use syn::parse::{ParseStream, Parser}; -use syn::{Ident, Index, LitStr, Member, Result, Token}; - -impl Display<'_> { - // Transform `"error {var}"` to `"error {}", var`. - pub fn expand_shorthand(&mut self, fields: &[Field]) { - let raw_args = self.args.clone(); - let mut named_args = explicit_named_args.parse2(raw_args).unwrap(); - let mut member_index = Map::new(); - for (i, field) in fields.iter().enumerate() { - member_index.insert(&field.member, i); - } - - let span = self.fmt.span(); - let fmt = self.fmt.value(); - let mut read = fmt.as_str(); - let mut out = String::new(); - let mut args = self.args.clone(); - let mut has_bonus_display = false; - let mut implied_bounds = Set::new(); - - let mut has_trailing_comma = false; - if let Some(TokenTree::Punct(punct)) = args.clone().into_iter().last() { - if punct.as_char() == ',' { - has_trailing_comma = true; - } - } - - while let Some(brace) = read.find('{') { - out += &read[..brace + 1]; - read = &read[brace + 1..]; - if read.starts_with('{') { - out.push('{'); - read = &read[1..]; - continue; - } - let next = match read.chars().next() { - Some(next) => next, - None => return, - }; - let member = match next { - '0'..='9' => { - let int = take_int(&mut read); - let member = match int.parse::<u32>() { - Ok(index) => Member::Unnamed(Index { index, span }), - Err(_) => return, - }; - if !member_index.contains_key(&member) { - out += ∫ - continue; - } - member - } - 'a'..='z' | 'A'..='Z' | '_' => { - let mut ident = take_ident(&mut read); - ident.set_span(span); - Member::Named(ident) - } - _ => continue, - }; - if let Some(&field) = member_index.get(&member) { - let end_spec = match read.find('}') { - Some(end_spec) => end_spec, - None => return, - }; - let bound = match read[..end_spec].chars().next_back() { - Some('?') => Trait::Debug, - Some('o') => Trait::Octal, - Some('x') => Trait::LowerHex, - Some('X') => Trait::UpperHex, - Some('p') => Trait::Pointer, - Some('b') => Trait::Binary, - Some('e') => Trait::LowerExp, - Some('E') => Trait::UpperExp, - Some(_) | None => Trait::Display, - }; - implied_bounds.insert((field, bound)); - } - let local = match &member { - Member::Unnamed(index) => format_ident!("_{}", index), - Member::Named(ident) => ident.clone(), - }; - let mut formatvar = local.clone(); - if formatvar.to_string().starts_with("r#") { - formatvar = format_ident!("r_{}", formatvar); - } - if formatvar.to_string().starts_with('_') { - // Work around leading underscore being rejected by 1.40 and - // older compilers. https://github.com/rust-lang/rust/pull/66847 - formatvar = format_ident!("field_{}", formatvar); - } - out += &formatvar.to_string(); - if !named_args.insert(formatvar.clone()) { - // Already specified in the format argument list. - continue; - } - if !has_trailing_comma { - args.extend(quote_spanned!(span=> ,)); - } - args.extend(quote_spanned!(span=> #formatvar = #local)); - if read.starts_with('}') && member_index.contains_key(&member) { - has_bonus_display = true; - args.extend(quote_spanned!(span=> .as_display())); - } - has_trailing_comma = false; - } - - out += read; - self.fmt = LitStr::new(&out, self.fmt.span()); - self.args = args; - self.has_bonus_display = has_bonus_display; - self.implied_bounds = implied_bounds; - } -} - -fn explicit_named_args(input: ParseStream) -> Result<Set<Ident>> { - let mut named_args = Set::new(); - - while !input.is_empty() { - if input.peek(Token![,]) && input.peek2(Ident::peek_any) && input.peek3(Token![=]) { - input.parse::<Token![,]>()?; - let ident = input.call(Ident::parse_any)?; - input.parse::<Token![=]>()?; - named_args.insert(ident); - } else { - input.parse::<TokenTree>()?; - } - } - - Ok(named_args) -} - -fn take_int(read: &mut &str) -> String { - let mut int = String::new(); - for (i, ch) in read.char_indices() { - match ch { - '0'..='9' => int.push(ch), - _ => { - *read = &read[i..]; - break; - } - } - } - int -} - -fn take_ident(read: &mut &str) -> Ident { - let mut ident = String::new(); - let raw = read.starts_with("r#"); - if raw { - ident.push_str("r#"); - *read = &read[2..]; - } - for (i, ch) in read.char_indices() { - match ch { - 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' => ident.push(ch), - _ => { - *read = &read[i..]; - break; - } - } - } - Ident::parse_any.parse_str(&ident).unwrap() -} diff --git a/vendor/thiserror-impl/src/generics.rs b/vendor/thiserror-impl/src/generics.rs deleted file mode 100644 index 95592a7..0000000 --- a/vendor/thiserror-impl/src/generics.rs +++ /dev/null @@ -1,83 +0,0 @@ -use proc_macro2::TokenStream; -use quote::ToTokens; -use std::collections::btree_map::Entry; -use std::collections::{BTreeMap as Map, BTreeSet as Set}; -use syn::punctuated::Punctuated; -use syn::{parse_quote, GenericArgument, Generics, Ident, PathArguments, Token, Type, WhereClause}; - -pub struct ParamsInScope<'a> { - names: Set<&'a Ident>, -} - -impl<'a> ParamsInScope<'a> { - pub fn new(generics: &'a Generics) -> Self { - ParamsInScope { - names: generics.type_params().map(|param| ¶m.ident).collect(), - } - } - - pub fn intersects(&self, ty: &Type) -> bool { - let mut found = false; - crawl(self, ty, &mut found); - found - } -} - -fn crawl(in_scope: &ParamsInScope, ty: &Type, found: &mut bool) { - if let Type::Path(ty) = ty { - if ty.qself.is_none() { - if let Some(ident) = ty.path.get_ident() { - if in_scope.names.contains(ident) { - *found = true; - } - } - } - for segment in &ty.path.segments { - if let PathArguments::AngleBracketed(arguments) = &segment.arguments { - for arg in &arguments.args { - if let GenericArgument::Type(ty) = arg { - crawl(in_scope, ty, found); - } - } - } - } - } -} - -pub struct InferredBounds { - bounds: Map<String, (Set<String>, Punctuated<TokenStream, Token![+]>)>, - order: Vec<TokenStream>, -} - -impl InferredBounds { - pub fn new() -> Self { - InferredBounds { - bounds: Map::new(), - order: Vec::new(), - } - } - - #[allow(clippy::type_repetition_in_bounds, clippy::trait_duplication_in_bounds)] // clippy bug: https://github.com/rust-lang/rust-clippy/issues/8771 - pub fn insert(&mut self, ty: impl ToTokens, bound: impl ToTokens) { - let ty = ty.to_token_stream(); - let bound = bound.to_token_stream(); - let entry = self.bounds.entry(ty.to_string()); - if let Entry::Vacant(_) = entry { - self.order.push(ty); - } - let (set, tokens) = entry.or_default(); - if set.insert(bound.to_string()) { - tokens.push(bound); - } - } - - pub fn augment_where_clause(&self, generics: &Generics) -> WhereClause { - let mut generics = generics.clone(); - let where_clause = generics.make_where_clause(); - for ty in &self.order { - let (_set, bounds) = &self.bounds[&ty.to_string()]; - where_clause.predicates.push(parse_quote!(#ty: #bounds)); - } - generics.where_clause.unwrap() - } -} diff --git a/vendor/thiserror-impl/src/lib.rs b/vendor/thiserror-impl/src/lib.rs deleted file mode 100644 index 58f4bb5..0000000 --- a/vendor/thiserror-impl/src/lib.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![allow( - clippy::blocks_in_conditions, - clippy::cast_lossless, - clippy::cast_possible_truncation, - clippy::manual_find, - clippy::manual_let_else, - clippy::manual_map, - clippy::map_unwrap_or, - clippy::module_name_repetitions, - clippy::needless_pass_by_value, - clippy::range_plus_one, - clippy::single_match_else, - clippy::struct_field_names, - clippy::too_many_lines, - clippy::wrong_self_convention -)] - -extern crate proc_macro; - -mod ast; -mod attr; -mod expand; -mod fmt; -mod generics; -mod prop; -mod span; -mod valid; - -use proc_macro::TokenStream; -use syn::{parse_macro_input, DeriveInput}; - -#[proc_macro_derive(Error, attributes(backtrace, error, from, source))] -pub fn derive_error(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as DeriveInput); - expand::derive(&input).into() -} diff --git a/vendor/thiserror-impl/src/prop.rs b/vendor/thiserror-impl/src/prop.rs deleted file mode 100644 index 2867cd3..0000000 --- a/vendor/thiserror-impl/src/prop.rs +++ /dev/null @@ -1,147 +0,0 @@ -use crate::ast::{Enum, Field, Struct, Variant}; -use crate::span::MemberSpan; -use proc_macro2::Span; -use syn::{Member, Type}; - -impl Struct<'_> { - pub(crate) fn from_field(&self) -> Option<&Field> { - from_field(&self.fields) - } - - pub(crate) fn source_field(&self) -> Option<&Field> { - source_field(&self.fields) - } - - pub(crate) fn backtrace_field(&self) -> Option<&Field> { - backtrace_field(&self.fields) - } - - pub(crate) fn distinct_backtrace_field(&self) -> Option<&Field> { - let backtrace_field = self.backtrace_field()?; - distinct_backtrace_field(backtrace_field, self.from_field()) - } -} - -impl Enum<'_> { - pub(crate) fn has_source(&self) -> bool { - self.variants - .iter() - .any(|variant| variant.source_field().is_some() || variant.attrs.transparent.is_some()) - } - - pub(crate) fn has_backtrace(&self) -> bool { - self.variants - .iter() - .any(|variant| variant.backtrace_field().is_some()) - } - - pub(crate) fn has_display(&self) -> bool { - self.attrs.display.is_some() - || self.attrs.transparent.is_some() - || self - .variants - .iter() - .any(|variant| variant.attrs.display.is_some()) - || self - .variants - .iter() - .all(|variant| variant.attrs.transparent.is_some()) - } -} - -impl Variant<'_> { - pub(crate) fn from_field(&self) -> Option<&Field> { - from_field(&self.fields) - } - - pub(crate) fn source_field(&self) -> Option<&Field> { - source_field(&self.fields) - } - - pub(crate) fn backtrace_field(&self) -> Option<&Field> { - backtrace_field(&self.fields) - } - - pub(crate) fn distinct_backtrace_field(&self) -> Option<&Field> { - let backtrace_field = self.backtrace_field()?; - distinct_backtrace_field(backtrace_field, self.from_field()) - } -} - -impl Field<'_> { - pub(crate) fn is_backtrace(&self) -> bool { - type_is_backtrace(self.ty) - } - - pub(crate) fn source_span(&self) -> Span { - if let Some(source_attr) = &self.attrs.source { - source_attr.path().get_ident().unwrap().span() - } else if let Some(from_attr) = &self.attrs.from { - from_attr.path().get_ident().unwrap().span() - } else { - self.member.member_span() - } - } -} - -fn from_field<'a, 'b>(fields: &'a [Field<'b>]) -> Option<&'a Field<'b>> { - for field in fields { - if field.attrs.from.is_some() { - return Some(field); - } - } - None -} - -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() { - return Some(field); - } - } - for field in fields { - match &field.member { - Member::Named(ident) if ident == "source" => return Some(field), - _ => {} - } - } - None -} - -fn backtrace_field<'a, 'b>(fields: &'a [Field<'b>]) -> Option<&'a Field<'b>> { - for field in fields { - if field.attrs.backtrace.is_some() { - return Some(field); - } - } - for field in fields { - if field.is_backtrace() { - return Some(field); - } - } - None -} - -// The #[backtrace] field, if it is not the same as the #[from] field. -fn distinct_backtrace_field<'a, 'b>( - backtrace_field: &'a Field<'b>, - from_field: Option<&Field>, -) -> Option<&'a Field<'b>> { - if from_field.map_or(false, |from_field| { - from_field.member == backtrace_field.member - }) { - None - } else { - Some(backtrace_field) - } -} - -fn type_is_backtrace(ty: &Type) -> bool { - let path = match ty { - Type::Path(ty) => &ty.path, - _ => return false, - }; - - let last = path.segments.last().unwrap(); - last.ident == "Backtrace" && last.arguments.is_empty() -} diff --git a/vendor/thiserror-impl/src/span.rs b/vendor/thiserror-impl/src/span.rs deleted file mode 100644 index c1237dd..0000000 --- a/vendor/thiserror-impl/src/span.rs +++ /dev/null @@ -1,15 +0,0 @@ -use proc_macro2::Span; -use syn::Member; - -pub trait MemberSpan { - fn member_span(&self) -> Span; -} - -impl MemberSpan for Member { - fn member_span(&self) -> Span { - match self { - Member::Named(ident) => ident.span(), - Member::Unnamed(index) => index.span, - } - } -} diff --git a/vendor/thiserror-impl/src/valid.rs b/vendor/thiserror-impl/src/valid.rs deleted file mode 100644 index cf5b859..0000000 --- a/vendor/thiserror-impl/src/valid.rs +++ /dev/null @@ -1,237 +0,0 @@ -use crate::ast::{Enum, Field, Input, Struct, Variant}; -use crate::attr::Attrs; -use quote::ToTokens; -use std::collections::BTreeSet as Set; -use syn::{Error, GenericArgument, Member, PathArguments, Result, Type}; - -impl Input<'_> { - pub(crate) fn validate(&self) -> Result<()> { - match self { - Input::Struct(input) => input.validate(), - Input::Enum(input) => input.validate(), - } - } -} - -impl Struct<'_> { - fn validate(&self) -> Result<()> { - check_non_field_attrs(&self.attrs)?; - if let Some(transparent) = self.attrs.transparent { - if self.fields.len() != 1 { - return Err(Error::new_spanned( - transparent.original, - "#[error(transparent)] requires exactly one field", - )); - } - if let Some(source) = self.fields.iter().find_map(|f| f.attrs.source) { - return Err(Error::new_spanned( - source, - "transparent error struct can't contain #[source]", - )); - } - } - check_field_attrs(&self.fields)?; - for field in &self.fields { - field.validate()?; - } - Ok(()) - } -} - -impl Enum<'_> { - fn validate(&self) -> Result<()> { - check_non_field_attrs(&self.attrs)?; - let has_display = self.has_display(); - for variant in &self.variants { - variant.validate()?; - if has_display && variant.attrs.display.is_none() && variant.attrs.transparent.is_none() - { - return Err(Error::new_spanned( - variant.original, - "missing #[error(\"...\")] display attribute", - )); - } - } - let mut from_types = Set::new(); - for variant in &self.variants { - if let Some(from_field) = variant.from_field() { - let repr = from_field.ty.to_token_stream().to_string(); - if !from_types.insert(repr) { - return Err(Error::new_spanned( - from_field.original, - "cannot derive From because another variant has the same source type", - )); - } - } - } - Ok(()) - } -} - -impl Variant<'_> { - fn validate(&self) -> Result<()> { - check_non_field_attrs(&self.attrs)?; - if self.attrs.transparent.is_some() { - if self.fields.len() != 1 { - return Err(Error::new_spanned( - self.original, - "#[error(transparent)] requires exactly one field", - )); - } - if let Some(source) = self.fields.iter().find_map(|f| f.attrs.source) { - return Err(Error::new_spanned( - source, - "transparent variant can't contain #[source]", - )); - } - } - check_field_attrs(&self.fields)?; - for field in &self.fields { - field.validate()?; - } - Ok(()) - } -} - -impl Field<'_> { - fn validate(&self) -> Result<()> { - if let Some(display) = &self.attrs.display { - return Err(Error::new_spanned( - display.original, - "not expected here; the #[error(...)] attribute belongs on top of a struct or an enum variant", - )); - } - Ok(()) - } -} - -fn check_non_field_attrs(attrs: &Attrs) -> Result<()> { - if let Some(from) = &attrs.from { - return Err(Error::new_spanned( - from, - "not expected here; the #[from] attribute belongs on a specific field", - )); - } - if let Some(source) = &attrs.source { - return Err(Error::new_spanned( - source, - "not expected here; the #[source] attribute belongs on a specific field", - )); - } - if let Some(backtrace) = &attrs.backtrace { - return Err(Error::new_spanned( - backtrace, - "not expected here; the #[backtrace] attribute belongs on a specific field", - )); - } - if let Some(display) = &attrs.display { - if attrs.transparent.is_some() { - return Err(Error::new_spanned( - display.original, - "cannot have both #[error(transparent)] and a display attribute", - )); - } - } - Ok(()) -} - -fn check_field_attrs(fields: &[Field]) -> Result<()> { - let mut from_field = None; - let mut source_field = None; - let mut backtrace_field = None; - let mut has_backtrace = false; - for field in fields { - if let Some(from) = field.attrs.from { - if from_field.is_some() { - return Err(Error::new_spanned(from, "duplicate #[from] attribute")); - } - from_field = Some(field); - } - if let Some(source) = field.attrs.source { - if source_field.is_some() { - return Err(Error::new_spanned(source, "duplicate #[source] attribute")); - } - source_field = Some(field); - } - if let Some(backtrace) = field.attrs.backtrace { - if backtrace_field.is_some() { - return Err(Error::new_spanned( - backtrace, - "duplicate #[backtrace] attribute", - )); - } - backtrace_field = Some(field); - has_backtrace = true; - } - if let Some(transparent) = field.attrs.transparent { - return Err(Error::new_spanned( - transparent.original, - "#[error(transparent)] needs to go outside the enum or struct, not on an individual field", - )); - } - has_backtrace |= field.is_backtrace(); - } - if let (Some(from_field), Some(source_field)) = (from_field, source_field) { - if !same_member(from_field, source_field) { - return Err(Error::new_spanned( - from_field.attrs.from, - "#[from] is only supported on the source field, not any other field", - )); - } - } - if let Some(from_field) = from_field { - let max_expected_fields = match backtrace_field { - Some(backtrace_field) => 1 + !same_member(from_field, backtrace_field) as usize, - None => 1 + has_backtrace as usize, - }; - if fields.len() > max_expected_fields { - return Err(Error::new_spanned( - from_field.attrs.from, - "deriving From requires no fields other than source and backtrace", - )); - } - } - if let Some(source_field) = source_field.or(from_field) { - if contains_non_static_lifetime(source_field.ty) { - return Err(Error::new_spanned( - &source_field.original.ty, - "non-static lifetimes are not allowed in the source of an error, because std::error::Error requires the source is dyn Error + 'static", - )); - } - } - Ok(()) -} - -fn same_member(one: &Field, two: &Field) -> bool { - match (&one.member, &two.member) { - (Member::Named(one), Member::Named(two)) => one == two, - (Member::Unnamed(one), Member::Unnamed(two)) => one.index == two.index, - _ => unreachable!(), - } -} - -fn contains_non_static_lifetime(ty: &Type) -> bool { - match ty { - Type::Path(ty) => { - let bracketed = match &ty.path.segments.last().unwrap().arguments { - PathArguments::AngleBracketed(bracketed) => bracketed, - _ => return false, - }; - for arg in &bracketed.args { - match arg { - GenericArgument::Type(ty) if contains_non_static_lifetime(ty) => return true, - GenericArgument::Lifetime(lifetime) if lifetime.ident != "static" => { - return true - } - _ => {} - } - } - false - } - Type::Reference(ty) => ty - .lifetime - .as_ref() - .map_or(false, |lifetime| lifetime.ident != "static"), - _ => false, // maybe implement later if there are common other cases - } -} |