diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-06-15 21:45:44 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-06-15 21:45:44 +0000 |
commit | 923b6ae86869e30975aff620c995f49ca6d9bf92 (patch) | |
tree | 55288574ba91873099b9261dd61f9d1ab82b84e8 | |
parent | 0287f7ed5f3d2280a226ee7a659affffab79a909 (diff) | |
parent | 5c9f86bcc640cc6face7d5dc55896cdff801a9ee (diff) | |
download | thiserror-impl-923b6ae86869e30975aff620c995f49ca6d9bf92.tar.gz |
Snap for 8730993 from 5c9f86bcc640cc6face7d5dc55896cdff801a9ee to mainline-tzdata3-releaseaml_tz3_314012070aml_tz3_314012050aml_tz3_314012010aml_tz3_313110000aml_tz3_312511020aml_tz3_312511010aml_tz3_312410020aml_tz3_312410010android12-mainline-tzdata3-releaseaml_tz3_314012010
Change-Id: I6de340372b46843c054fbe9315907678047ded75
-rw-r--r-- | .cargo_vcs_info.json | 7 | ||||
-rw-r--r-- | Android.bp | 10 | ||||
-rw-r--r-- | Cargo.toml | 12 | ||||
-rw-r--r-- | Cargo.toml.orig | 3 | ||||
-rw-r--r-- | METADATA | 10 | ||||
-rw-r--r-- | TEST_MAPPING | 125 | ||||
-rw-r--r-- | cargo2android.json | 4 | ||||
-rw-r--r-- | src/ast.rs | 28 | ||||
-rw-r--r-- | src/attr.rs | 23 | ||||
-rw-r--r-- | src/expand.rs | 148 | ||||
-rw-r--r-- | src/fmt.rs | 33 | ||||
-rw-r--r-- | src/generics.rs | 82 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/prop.rs | 34 | ||||
-rw-r--r-- | src/valid.rs | 2 |
15 files changed, 75 insertions, 448 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 2d04484..349cbda 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,5 @@ { "git": { - "sha1": "672e9525bbc2e5682c380d36974f34716b963591" - }, - "path_in_vcs": "impl" -}
\ No newline at end of file + "sha1": "1b0a84996b9492c0dc5779127a91c930f23a259e" + } +} @@ -1,4 +1,4 @@ -// This file is generated by cargo2android.py --config cargo2android.json. +// This file is generated by cargo2android.py --run --dependencies --device. // Do not modify this file as changes will be overridden on upgrade. package { @@ -42,8 +42,6 @@ license { rust_proc_macro { name: "libthiserror_impl", crate_name: "thiserror_impl", - cargo_env_compat: true, - cargo_pkg_version: "1.0.30", srcs: ["src/lib.rs"], edition: "2018", rustlibs: [ @@ -52,3 +50,9 @@ rust_proc_macro { "libsyn", ], } + +// dependent_library ["feature_list"] +// proc-macro2-1.0.24 "default,proc-macro" +// quote-1.0.9 "default,proc-macro" +// syn-1.0.60 "clone-impls,default,derive,parsing,printing,proc-macro,quote" +// unicode-xid-0.2.1 "default" @@ -3,17 +3,17 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies. +# to registry (e.g., crates.io) dependencies # -# If you are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) [package] edition = "2018" -rust-version = "1.31" name = "thiserror-impl" -version = "1.0.30" +version = "1.0.24" authors = ["David Tolnay <dtolnay@gmail.com>"] description = "Implementation detail of the `thiserror` crate" license = "MIT OR Apache-2.0" diff --git a/Cargo.toml.orig b/Cargo.toml.orig index e2ad11b..3963fe2 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,9 +1,8 @@ [package] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.24" authors = ["David Tolnay <dtolnay@gmail.com>"] edition = "2018" -rust-version = "1.31" license = "MIT OR Apache-2.0" description = "Implementation detail of the `thiserror` crate" repository = "https://github.com/dtolnay/thiserror" @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/thiserror-impl/thiserror-impl-1.0.30.crate" + value: "https://static.crates.io/crates/thiserror-impl/thiserror-impl-1.0.24.crate" } - version: "1.0.30" + version: "1.0.24" license_type: NOTICE last_upgrade_date { - year: 2022 - month: 3 - day: 1 + year: 2021 + month: 2 + day: 18 } } diff --git a/TEST_MAPPING b/TEST_MAPPING index eea7991..743367a 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -1,150 +1,53 @@ // Generated by update_crate_tests.py for tests that depend on this crate. { - "imports": [ - { - "path": "external/rust/crates/anyhow" - }, - { - "path": "external/rust/crates/jni" - }, - { - "path": "external/rust/crates/serde-xml-rs" - } - ], "presubmit": [ { - "name": "ZipFuseTest" - }, - { - "name": "apkdmverity.test" - }, - { - "name": "authfs_device_test_src_lib" - }, - { - "name": "diced_open_dice_cbor_test" - }, - { - "name": "diced_sample_inputs_test" - }, - { - "name": "diced_test" - }, - { - "name": "diced_utils_test" - }, - { - "name": "diced_vendor_test" - }, - { - "name": "doh_unit_test" - }, - { - "name": "keystore2_crypto_test_rust" - }, - { - "name": "keystore2_selinux_concurrency_test" + "name": "anyhow_device_test_tests_test_autotrait" }, { "name": "keystore2_selinux_test" }, { - "name": "keystore2_test" - }, - { - "name": "keystore2_test_utils_test" - }, - { - "name": "keystore2_vintf_test" - }, - { - "name": "legacykeystore_test" + "name": "anyhow_device_test_tests_test_repr" }, { - "name": "libapkverify.integration_test" + "name": "anyhow_device_test_tests_test_convert" }, { - "name": "libapkverify.test" + "name": "anyhow_device_test_tests_test_context" }, { - "name": "libcert_request_validator_tests" + "name": "anyhow_device_test_tests_test_boxed" }, { - "name": "librustutils_test" - }, - { - "name": "microdroid_manager_test" - }, - { - "name": "virtualizationservice_device_test" - } - ], - "presubmit-rust": [ - { - "name": "ZipFuseTest" - }, - { - "name": "apkdmverity.test" - }, - { - "name": "authfs_device_test_src_lib" - }, - { - "name": "diced_open_dice_cbor_test" - }, - { - "name": "diced_sample_inputs_test" - }, - { - "name": "diced_test" - }, - { - "name": "diced_utils_test" - }, - { - "name": "diced_vendor_test" - }, - { - "name": "doh_unit_test" - }, - { - "name": "keystore2_crypto_test_rust" - }, - { - "name": "keystore2_selinux_concurrency_test" - }, - { - "name": "keystore2_selinux_test" + "name": "anyhow_device_test_tests_test_downcast" }, { "name": "keystore2_test" }, { - "name": "keystore2_test_utils_test" - }, - { - "name": "keystore2_vintf_test" + "name": "anyhow_device_test_tests_test_source" }, { - "name": "legacykeystore_test" + "name": "anyhow_device_test_src_lib" }, { - "name": "libapkverify.integration_test" + "name": "anyhow_device_test_tests_test_fmt" }, { - "name": "libapkverify.test" + "name": "anyhow_device_test_tests_test_ffi" }, { - "name": "libcert_request_validator_tests" + "name": "anyhow_device_test_tests_test_chain" }, { - "name": "librustutils_test" + "name": "libsqlite3-sys_device_test_src_lib" }, { - "name": "microdroid_manager_test" + "name": "keystore2_crypto_test_rust" }, { - "name": "virtualizationservice_device_test" + "name": "anyhow_device_test_tests_test_macros" } ] } diff --git a/cargo2android.json b/cargo2android.json deleted file mode 100644 index bf78496..0000000 --- a/cargo2android.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "device": true, - "run": true -}
\ No newline at end of file @@ -1,5 +1,4 @@ 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, @@ -39,7 +38,6 @@ pub struct Field<'a> { pub attrs: Attrs<'a>, pub member: Member, pub ty: &'a Type, - pub contains_generic: bool, } impl<'a> Input<'a> { @@ -58,9 +56,8 @@ impl<'a> Input<'a> { 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)?; + let fields = Field::multiple_from_syn(&data.fields, span)?; if let Some(display) = &mut attrs.display { display.expand_shorthand(&fields); } @@ -77,13 +74,12 @@ impl<'a> Struct<'a> { 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)?; + let mut variant = Variant::from_syn(node, span)?; if let display @ None = &mut variant.attrs.display { *display = attrs.display.clone(); } @@ -106,37 +102,28 @@ impl<'a> Enum<'a> { } impl<'a> Variant<'a> { - fn from_syn(node: &'a syn::Variant, scope: &ParamsInScope<'a>, span: Span) -> Result<Self> { + fn from_syn(node: &'a syn::Variant, 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)?, + fields: Field::multiple_from_syn(&node.fields, span)?, }) } } impl<'a> Field<'a> { - fn multiple_from_syn( - fields: &'a Fields, - scope: &ParamsInScope<'a>, - span: Span, - ) -> Result<Vec<Self>> { + fn multiple_from_syn(fields: &'a Fields, span: Span) -> Result<Vec<Self>> { fields .iter() .enumerate() - .map(|(i, field)| Field::from_syn(i, field, scope, span)) + .map(|(i, field)| Field::from_syn(i, field, span)) .collect() } - fn from_syn( - i: usize, - node: &'a syn::Field, - scope: &ParamsInScope<'a>, - span: Span, - ) -> Result<Self> { + fn from_syn(i: usize, node: &'a syn::Field, span: Span) -> Result<Self> { Ok(Field { original: node, attrs: attr::get(&node.attrs)?, @@ -147,7 +134,6 @@ impl<'a> Field<'a> { }) }), ty: &node.ty, - contains_generic: scope.intersects(&node.ty), }) } } diff --git a/src/attr.rs b/src/attr.rs index 9963fd6..1ab1e28 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -1,6 +1,5 @@ use proc_macro2::{Delimiter, Group, Span, TokenStream, TokenTree}; use quote::{format_ident, quote, ToTokens}; -use std::collections::BTreeSet as Set; use std::iter::FromIterator; use syn::parse::{Nothing, ParseStream}; use syn::{ @@ -22,7 +21,6 @@ pub struct Display<'a> { pub fmt: LitStr, pub args: TokenStream, pub has_bonus_display: bool, - pub implied_bounds: Set<(usize, Trait)>, } #[derive(Copy, Clone)] @@ -31,19 +29,6 @@ pub struct Transparent<'a> { 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, @@ -106,7 +91,6 @@ fn parse_error_attribute<'a>(attrs: &mut Attrs<'a>, attr: &'a Attribute) -> Resu 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( @@ -204,10 +188,3 @@ impl ToTokens for Display<'_> { }); } } - -impl ToTokens for Trait { - fn to_tokens(&self, tokens: &mut TokenStream) { - let trait_name = format_ident!("{}", format!("{:?}", self)); - tokens.extend(quote!(std::fmt::#trait_name)); - } -} diff --git a/src/expand.rs b/src/expand.rs index 435ad48..fa85cbb 100644 --- a/src/expand.rs +++ b/src/expand.rs @@ -1,13 +1,8 @@ use crate::ast::{Enum, Field, Input, Struct}; -use crate::attr::Trait; -use crate::generics::InferredBounds; use proc_macro2::TokenStream; use quote::{format_ident, quote, quote_spanned, ToTokens}; -use std::collections::BTreeSet as Set; use syn::spanned::Spanned; -use syn::{ - Data, DeriveInput, GenericArgument, Member, PathArguments, Result, Token, Type, Visibility, -}; +use syn::{Data, DeriveInput, Member, PathArguments, Result, Type, Visibility}; pub fn derive(node: &DeriveInput) -> Result<TokenStream> { let input = Input::from_syn(node)?; @@ -21,23 +16,14 @@ pub fn derive(node: &DeriveInput) -> Result<TokenStream> { 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 input.attrs.transparent.is_some() { - 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; + let only_field = &input.fields[0].member; Some(quote! { - std::error::Error::source(self.#member.as_dyn_error()) + std::error::Error::source(self.#only_field.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.span()=> .as_ref()?)) } else { @@ -72,9 +58,7 @@ fn impl_struct(input: Struct) -> TokenStream { self.#source.as_dyn_error().backtrace() } }; - let combinator = if source == backtrace { - source_backtrace - } else if type_is_option(backtrace_field.ty) { + let combinator = if type_is_option(backtrace_field.ty) { quote! { #source_backtrace.or(self.#backtrace.as_ref()) } @@ -103,15 +87,12 @@ fn impl_struct(input: Struct) -> TokenStream { } }); - 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! { std::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 = if display.has_bonus_display { Some(quote! { #[allow(unused_imports)] @@ -131,17 +112,9 @@ fn impl_struct(input: Struct) -> TokenStream { 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 std::fmt::Display for #ty #ty_generics #display_where_clause { + impl #impl_generics std::fmt::Display for #ty #ty_generics #where_clause { #[allow(clippy::used_underscore_binding)] fn fmt(&self, __formatter: &mut std::fmt::Formatter) -> std::fmt::Result { #body @@ -151,8 +124,8 @@ fn impl_struct(input: Struct) -> TokenStream { }); let from_impl = input.from_field().map(|from_field| { - let backtrace_field = input.distinct_backtrace_field(); - let from = unoptional_type(from_field.ty); + let backtrace_field = input.backtrace_field(); + let from = from_field.ty; let body = from_initializer(from_field, backtrace_field); quote! { #[allow(unused_qualifications)] @@ -166,16 +139,10 @@ fn impl_struct(input: Struct) -> TokenStream { }); let error_trait = spanned_error_trait(input.original); - 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 #error_trait for #ty #ty_generics #error_where_clause { + impl #impl_generics #error_trait for #ty #ty_generics #where_clause { #source_method #backtrace_method } @@ -187,27 +154,18 @@ fn impl_struct(input: Struct) -> TokenStream { 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 variant.attrs.transparent.is_some() { - 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 only_field = &variant.fields[0].member; let source = quote!(std::error::Error::source(transparent.as_dyn_error())); quote! { - #ty::#ident {#member: transparent} => #source, + #ty::#ident {#only_field: 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.span()=> .as_ref()?)) } else { @@ -276,27 +234,6 @@ fn impl_enum(input: Enum) -> TokenStream { } } } - (Some(backtrace_field), Some(source_field)) - if backtrace_field.member == source_field.member => - { - let backtrace = &backtrace_field.member; - let varsource = quote!(source); - let source_backtrace = if type_is_option(source_field.ty) { - quote_spanned! {backtrace.span()=> - #varsource.as_ref().and_then(|source| source.as_dyn_error().backtrace()) - } - } else { - quote_spanned! {backtrace.span()=> - #varsource.as_dyn_error().backtrace() - } - }; - quote! { - #ty::#ident {#backtrace: #varsource, ..} => { - use thiserror::private::AsDynError; - #source_backtrace - } - } - } (Some(backtrace_field), _) => { let backtrace = &backtrace_field.member; let body = if type_is_option(backtrace_field.ty) { @@ -326,7 +263,6 @@ fn impl_enum(input: Enum) -> TokenStream { }; let display_impl = if input.has_display() { - let mut display_inferred_bounds = InferredBounds::new(); let use_as_display = if input.variants.iter().any(|v| { v.attrs .display @@ -346,38 +282,25 @@ fn impl_enum(input: Enum) -> TokenStream { 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() - } + Some(display) => 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!(std::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 std::fmt::Display for #ty #ty_generics #display_where_clause { + impl #impl_generics std::fmt::Display for #ty #ty_generics #where_clause { fn fmt(&self, __formatter: &mut std::fmt::Formatter) -> std::fmt::Result { #use_as_display #[allow(unused_variables, deprecated, clippy::used_underscore_binding)] @@ -393,9 +316,9 @@ fn impl_enum(input: Enum) -> TokenStream { let from_impls = input.variants.iter().filter_map(|variant| { let from_field = variant.from_field()?; - let backtrace_field = variant.distinct_backtrace_field(); + let backtrace_field = variant.backtrace_field(); let variant = &variant.ident; - let from = unoptional_type(from_field.ty); + let from = from_field.ty; let body = from_initializer(from_field, backtrace_field); Some(quote! { #[allow(unused_qualifications)] @@ -409,16 +332,10 @@ fn impl_enum(input: Enum) -> TokenStream { }); let error_trait = spanned_error_trait(input.original); - 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 #error_trait for #ty #ty_generics #error_where_clause { + impl #impl_generics #error_trait for #ty #ty_generics #where_clause { #source_method #backtrace_method } @@ -444,11 +361,6 @@ fn fields_pat(fields: &[Field]) -> TokenStream { 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!(std::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) { @@ -462,43 +374,25 @@ fn from_initializer(from_field: &Field, backtrace_field: Option<&Field>) -> Toke } }); quote!({ - #from_member: #some_source, + #from_member: 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, + _ => return false, }; 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; + return false; } - match &bracketed.args[0] { - GenericArgument::Type(arg) => Some(arg), - _ => None, + match &last.arguments { + PathArguments::AngleBracketed(bracketed) => bracketed.args.len() == 1, + _ => false, } } @@ -1,8 +1,8 @@ use crate::ast::Field; -use crate::attr::{Display, Trait}; +use crate::attr::Display; use proc_macro2::TokenTree; use quote::{format_ident, quote_spanned}; -use std::collections::{BTreeSet as Set, HashMap as Map}; +use std::collections::HashSet as Set; use syn::ext::IdentExt; use syn::parse::{ParseStream, Parser}; use syn::{Ident, Index, LitStr, Member, Result, Token}; @@ -12,10 +12,7 @@ impl Display<'_> { 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 fields: Set<Member> = fields.iter().map(|f| f.member.clone()).collect(); let span = self.fmt.span(); let fmt = self.fmt.value(); @@ -23,7 +20,6 @@ impl Display<'_> { 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() { @@ -51,7 +47,7 @@ impl Display<'_> { Ok(index) => Member::Unnamed(Index { index, span }), Err(_) => return, }; - if !member_index.contains_key(&member) { + if !fields.contains(&member) { out += ∫ continue; } @@ -64,24 +60,6 @@ impl Display<'_> { } _ => 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(), @@ -104,7 +82,7 @@ impl Display<'_> { args.extend(quote_spanned!(span=> ,)); } args.extend(quote_spanned!(span=> #formatvar = #local)); - if read.starts_with('}') && member_index.contains_key(&member) { + if read.starts_with('}') && fields.contains(&member) { has_bonus_display = true; args.extend(quote_spanned!(span=> .as_display())); } @@ -115,7 +93,6 @@ impl Display<'_> { self.fmt = LitStr::new(&out, self.fmt.span()); self.args = args; self.has_bonus_display = has_bonus_display; - self.implied_bounds = implied_bounds; } } diff --git a/src/generics.rs b/src/generics.rs deleted file mode 100644 index 254c2ed..0000000 --- a/src/generics.rs +++ /dev/null @@ -1,82 +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(), - } - } - - 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() - } -} @@ -1,7 +1,6 @@ #![allow( clippy::blocks_in_if_conditions, clippy::cast_possible_truncation, - clippy::manual_map, clippy::map_unwrap_or, clippy::needless_pass_by_value, clippy::option_if_let_else, @@ -16,7 +15,6 @@ mod ast; mod attr; mod expand; mod fmt; -mod generics; mod prop; mod valid; diff --git a/src/prop.rs b/src/prop.rs index 6d8a924..e011848 100644 --- a/src/prop.rs +++ b/src/prop.rs @@ -13,11 +13,6 @@ impl Struct<'_> { 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<'_> { @@ -59,11 +54,6 @@ impl Variant<'_> { 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<'_> { @@ -75,7 +65,7 @@ impl Field<'_> { 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); + return Some(&field); } } None @@ -84,12 +74,12 @@ fn from_field<'a, 'b>(fields: &'a [Field<'b>]) -> Option<&'a Field<'b>> { 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); + return Some(&field); } } for field in fields { match &field.member { - Member::Named(ident) if ident == "source" => return Some(field), + Member::Named(ident) if ident == "source" => return Some(&field), _ => {} } } @@ -99,31 +89,17 @@ fn source_field<'a, 'b>(fields: &'a [Field<'b>]) -> Option<&'a Field<'b>> { 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); + return Some(&field); } } for field in fields { if field.is_backtrace() { - return Some(field); + 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, diff --git a/src/valid.rs b/src/valid.rs index 7657265..7246d0c 100644 --- a/src/valid.rs +++ b/src/valid.rs @@ -188,7 +188,7 @@ fn check_field_attrs(fields: &[Field]) -> Result<()> { } } if let Some(source_field) = source_field.or(from_field) { - if contains_non_static_lifetime(source_field.ty) { + 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", |