diff options
Diffstat (limited to 'vendor/zerofrom-derive')
-rw-r--r-- | vendor/zerofrom-derive/.cargo-checksum.json | 2 | ||||
-rw-r--r-- | vendor/zerofrom-derive/Cargo.lock | 115 | ||||
-rw-r--r-- | vendor/zerofrom-derive/Cargo.toml | 19 | ||||
-rw-r--r-- | vendor/zerofrom-derive/LICENSE | 79 | ||||
-rw-r--r-- | vendor/zerofrom-derive/README.md | 4 | ||||
-rw-r--r-- | vendor/zerofrom-derive/examples/zf_derive.rs | 24 | ||||
-rw-r--r-- | vendor/zerofrom-derive/src/lib.rs | 149 | ||||
-rw-r--r-- | vendor/zerofrom-derive/src/visitor.rs | 20 |
8 files changed, 330 insertions, 82 deletions
diff --git a/vendor/zerofrom-derive/.cargo-checksum.json b/vendor/zerofrom-derive/.cargo-checksum.json index 2e4a173e0..18bdf7b25 100644 --- a/vendor/zerofrom-derive/.cargo-checksum.json +++ b/vendor/zerofrom-derive/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.lock":"c066c6ce9b35f0c703bfa8ac45bb6780d499edaa5cb6437dc498ac0c38d609d8","Cargo.toml":"57e4d1407e5cdb86ebf4e520fd01cfbc9448e1886f2ce5ef81ae5cf48c440e3e","LICENSE":"4ad7541d66a407234e2c84902124cef325c29f3e966353efdb800bedb8b8da21","README.md":"11a51a5a18692b4ba67b60b556c06cce8b0c81a0c7dd82f818893207840fb052","examples/zf_derive.rs":"16fca391d8aeff66575c6f4ca5587827a159eae561f94f49507984f76e9c884d","src/lib.rs":"6b6473461c8b5aed34c652e24affb2c067f62003c06f3251fdf10ba6f6639033","src/visitor.rs":"644492b09434a35d715f4d32c72db3184a9c05f26177d7492e816f063b25663c"},"package":"b4eae7c1f7d4b8eafce526bc0771449ddc2f250881ae31c50d22c032b5a1c499"}
\ No newline at end of file +{"files":{"Cargo.lock":"b62effc5afdc9fb930c8fbe35b9bd81ed4a1c2a1b565fbfe784368dc1fa0887e","Cargo.toml":"e9741aae41f8ae616b3dcb825b41778ba28302d7e8b6d95d9f5dfa00ea4e9bb1","LICENSE":"853f87c96f3d249f200fec6db1114427bc8bdf4afddc93c576956d78152ce978","README.md":"2ef78913a98fb26c912c47c3c96167b9b57524754dc4857fe18a2122fec4985e","examples/zf_derive.rs":"abc9e44e0baf26f2109b57c34fa69d6e550613dc7dad234c67eebd4bcde564a8","src/lib.rs":"ffca0d1bea178643e6855e084e36f85ce47f7ce0edc4b7faff086892c4cec650","src/visitor.rs":"74c1fd52b81e45d048f9fa8534ff2274e5e891ed320aede268265d2a51e742ce"},"package":"e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3"}
\ No newline at end of file diff --git a/vendor/zerofrom-derive/Cargo.lock b/vendor/zerofrom-derive/Cargo.lock index ff8b8debf..827c03e85 100644 --- a/vendor/zerofrom-derive/Cargo.lock +++ b/vendor/zerofrom-derive/Cargo.lock @@ -4,27 +4,64 @@ version = 3 [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -39,15 +76,27 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "285ba80e733fac80aa4270fbcdf83772a79b80aa35c97075320abfee4a915b06" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", "unicode-xid", ] [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-xid" @@ -56,11 +105,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] +name = "yoke" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e38c508604d6bbbd292dadb3c02559aa7fff6b654a078a36217cad871636e4" +dependencies = [ + "serde", + "stable_deref_trait", + "zerofrom", +] + +[[package]] +name = "zerofrom" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df54d76c3251de27615dfcce21e636c172dafb2549cd7fd93e21c66f6ca6bea2" +dependencies = [ + "zerofrom-derive 0.1.2", +] + +[[package]] name = "zerofrom-derive" version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4eae7c1f7d4b8eafce526bc0771449ddc2f250881ae31c50d22c032b5a1c499" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.3" dependencies = [ "proc-macro2", "quote", - "syn", - "synstructure", + "syn 2.0.37", + "synstructure 0.13.0", + "zerofrom", + "zerovec", +] + +[[package]] +name = "zerovec" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "198f54134cd865f437820aa3b43d0ad518af4e68ee161b444cdd15d8e567c8ea" +dependencies = [ + "yoke", + "zerofrom", ] diff --git a/vendor/zerofrom-derive/Cargo.toml b/vendor/zerofrom-derive/Cargo.toml index 66a5e8d94..46e1a26c3 100644 --- a/vendor/zerofrom-derive/Cargo.toml +++ b/vendor/zerofrom-derive/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2021" name = "zerofrom-derive" -version = "0.1.2" +version = "0.1.3" authors = ["Manish Goregaokar <manishsmail@gmail.com>"] description = "Custom derive for the zerofrom crate" readme = "README.md" @@ -28,7 +28,7 @@ categories = [ "caching", "no-std", ] -license = "Unicode-DFS-2016" +license-file = "LICENSE" repository = "https://github.com/unicode-org/icu4x" [package.metadata.workspaces] @@ -45,13 +45,22 @@ version = "1.0.27" version = "1.0.9" [dependencies.syn] -version = "1.0.73" +version = "2" features = [ "derive", "fold", + "visit", ] [dependencies.synstructure] -version = "0.12.4" +version = "0.13" -[dev-dependencies] +[dev-dependencies.zerofrom] +version = "0.1.1" +features = ["derive"] +default-features = false + +[dev-dependencies.zerovec] +version = "0.9.4" +features = ["yoke"] +default-features = false diff --git a/vendor/zerofrom-derive/LICENSE b/vendor/zerofrom-derive/LICENSE index 9858d01ab..9845aa5f4 100644 --- a/vendor/zerofrom-derive/LICENSE +++ b/vendor/zerofrom-derive/LICENSE @@ -1,49 +1,42 @@ -UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE - -See Terms of Use <https://www.unicode.org/copyright.html> -for definitions of Unicode Inc.’s Data Files and Software. - -NOTICE TO USER: Carefully read the following legal agreement. -BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S -DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), -YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE -TERMS AND CONDITIONS OF THIS AGREEMENT. -IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE -THE DATA FILES OR SOFTWARE. +UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE -Copyright © 1991-2022 Unicode, Inc. All rights reserved. -Distributed under the Terms of Use in https://www.unicode.org/copyright.html. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Unicode data files and any associated documentation -(the "Data Files") or Unicode software and any associated documentation -(the "Software") to deal in the Data Files or Software -without restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, and/or sell copies of -the Data Files or Software, and to permit persons to whom the Data Files -or Software are furnished to do so, provided that either -(a) this copyright and permission notice appear with all copies -of the Data Files or Software, or -(b) this copyright and permission notice appear in associated -Documentation. - -THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT OF THIRD PARTY RIGHTS. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS -NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL -DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THE DATA FILES OR SOFTWARE. - -Except as contained in this notice, the name of a copyright holder -shall not be used in advertising or otherwise to promote the sale, -use or other dealings in these Data Files or Software without prior -written authorization of the copyright holder. +Copyright © 2020-2023 Unicode, Inc. + +NOTICE TO USER: Carefully read the following legal agreement. BY +DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR +SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT +DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of data files and any associated documentation (the "Data Files") or +software and any associated documentation (the "Software") to deal in the +Data Files or Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell +copies of the Data Files or Software, and to permit persons to whom the +Data Files or Software are furnished to do so, provided that either (a) +this copyright and permission notice appear with all copies of the Data +Files or Software, or (b) this copyright and permission notice appear in +associated Documentation. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF +THIRD PARTY RIGHTS. + +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE +BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA +FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in these Data Files or Software without prior written +authorization of the copyright holder. — diff --git a/vendor/zerofrom-derive/README.md b/vendor/zerofrom-derive/README.md index 28e1a3a77..ad803c599 100644 --- a/vendor/zerofrom-derive/README.md +++ b/vendor/zerofrom-derive/README.md @@ -1,7 +1,11 @@ # zerofrom-derive [![crates.io](https://img.shields.io/crates/v/zerofrom-derive)](https://crates.io/crates/zerofrom-derive) +<!-- cargo-rdme start --> + Custom derives for `ZeroFrom` from the `zerofrom` crate. +<!-- cargo-rdme end --> + ## More Information For more information on development, authorship, contributing etc. please visit [`ICU4X home page`](https://github.com/unicode-org/icu4x). diff --git a/vendor/zerofrom-derive/examples/zf_derive.rs b/vendor/zerofrom-derive/examples/zf_derive.rs index 4f54c9464..a1bde8373 100644 --- a/vendor/zerofrom-derive/examples/zf_derive.rs +++ b/vendor/zerofrom-derive/examples/zf_derive.rs @@ -86,4 +86,28 @@ pub enum CloningZF3<'data> { Cow(#[zerofrom(clone)] Cow<'data, str>), } +#[derive(ZeroFrom)] +#[zerofrom(may_borrow(T))] // instead of treating T as a copy type, we want to allow zerofromming T too +pub struct GenericsThatAreAlsoZf<T> { + x: T, + y: Option<T>, +} + +pub fn assert_zf_generics_may_borrow<'a, 'b>( + x: &'b GenericsThatAreAlsoZf<&'a str>, +) -> GenericsThatAreAlsoZf<&'b str> { + GenericsThatAreAlsoZf::<&'b str>::zero_from(x) +} + +#[derive(ZeroFrom)] +pub struct UsesGenericsThatAreAlsoZf<'a> { + x: GenericsThatAreAlsoZf<&'a str>, +} + +// Ensure it works with invariant types too +#[derive(ZeroFrom)] +pub struct UsesGenericsThatAreAlsoZfWithMap<'a> { + x: GenericsThatAreAlsoZf<ZeroMap<'a, str, str>>, +} + fn main() {} diff --git a/vendor/zerofrom-derive/src/lib.rs b/vendor/zerofrom-derive/src/lib.rs index 5d6f1a81b..c6a3839fb 100644 --- a/vendor/zerofrom-derive/src/lib.rs +++ b/vendor/zerofrom-derive/src/lib.rs @@ -18,13 +18,19 @@ ) )] +use core::mem; use proc_macro::TokenStream; use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::quote; +use std::collections::{HashMap, HashSet}; +use syn::fold::{self, Fold}; +use syn::punctuated::Punctuated; use syn::spanned::Spanned; -use syn::{parse_macro_input, parse_quote, DeriveInput, Ident, Lifetime, Type, WherePredicate}; +use syn::{ + parse_macro_input, parse_quote, DeriveInput, Ident, Lifetime, MetaList, Token, Type, TypePath, + WherePredicate, +}; use synstructure::Structure; - mod visitor; /// Custom derive for `zerofrom::ZeroFrom`, @@ -35,16 +41,23 @@ mod visitor; /// /// Apply the `#[zerofrom(clone)]` attribute to a field if it doesn't implement /// Copy or ZeroFrom; this data will be cloned when the struct is zero_from'ed. +/// +/// Apply the `#[zerofrom(maybe_borrow(T, U, V))]` attribute to the struct to indicate +/// that certain type parameters may themselves contain borrows (by default +/// the derives assume that type parameters perform no borrows and can be copied or cloned). +/// +/// In rust versions where [this issue](https://github.com/rust-lang/rust/issues/114393) is fixed, +/// `#[zerofrom(may_borrow)]` can be applied directly to type parameters. #[proc_macro_derive(ZeroFrom, attributes(zerofrom))] pub fn zf_derive(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); TokenStream::from(zf_derive_impl(&input)) } -fn has_clone_attr(attrs: &[syn::Attribute]) -> bool { +fn has_attr(attrs: &[syn::Attribute], name: &str) -> bool { attrs.iter().any(|a| { if let Ok(i) = a.parse_args::<Ident>() { - if i == "clone" { + if i == name { return true; } } @@ -52,8 +65,29 @@ fn has_clone_attr(attrs: &[syn::Attribute]) -> bool { }) } +// Collects all idents from #[zerofrom(may_borrow(A, B, C, D))] +// needed since #[zerofrom(may_borrow)] doesn't work yet +// (https://github.com/rust-lang/rust/issues/114393) +fn get_may_borrow_attr(attrs: &[syn::Attribute]) -> Result<HashSet<Ident>, Span> { + let mut params = HashSet::new(); + for attr in attrs { + if let Ok(list) = attr.parse_args::<MetaList>() { + if list.path.is_ident("may_borrow") { + if let Ok(list) = + list.parse_args_with(Punctuated::<Ident, Token![,]>::parse_terminated) + { + params.extend(list) + } else { + return Err(attr.span()); + } + } + } + } + Ok(params) +} + fn zf_derive_impl(input: &DeriveInput) -> TokenStream2 { - let tybounds = input + let mut tybounds = input .generics .type_params() .map(|ty| { @@ -72,12 +106,47 @@ fn zf_derive_impl(input: &DeriveInput) -> TokenStream2 { let name = &input.ident; let structure = Structure::new(input); - if lts == 0 { + let may_borrow_attrs = match get_may_borrow_attr(&input.attrs) { + Ok(mb) => mb, + Err(span) => { + return syn::Error::new( + span, + "#[zerofrom(may_borrow)] on the struct takes in a comma separated list of type parameters, like so: `#[zerofrom(may_borrow(A, B, C, D)]`", + ).to_compile_error(); + } + }; + + // This contains every generic type introduced in this code. + // If the gneeric type is may_borrow, this additionally contains the identifier corresponding to + // a newly introduced mirror type parameter that we are borrowing from, similar to C in the original trait. + // For convenience, we are calling these "C types" + let generics_env: HashMap<Ident, Option<Ident>> = tybounds + .iter() + .map(|param| { + // First one doesn't work yet https://github.com/rust-lang/rust/issues/114393 + let maybe_new_param = if has_attr(¶m.attrs, "may_borrow") + || may_borrow_attrs.contains(¶m.ident) + { + Some(Ident::new( + &format!("{}ZFParamC", param.ident), + param.ident.span(), + )) + } else { + None + }; + (param.ident.clone(), maybe_new_param) + }) + .collect(); + + // Do any of the generics potentially borrow? + let generics_may_borrow = generics_env.values().any(|x| x.is_some()); + + if lts == 0 && !generics_may_borrow { let has_clone = structure .variants() .iter() .flat_map(|variant| variant.bindings().iter()) - .any(|binding| has_clone_attr(&binding.ast().attrs)); + .any(|binding| has_attr(&binding.ast().attrs, "clone")); let (clone, clone_trait) = if has_clone { (quote!(this.clone()), quote!(Clone)) } else { @@ -95,7 +164,7 @@ fn zf_derive_impl(input: &DeriveInput) -> TokenStream2 { } } } else { - if lts != 1 { + if lts > 1 { return syn::Error::new( input.generics.span(), "derive(ZeroFrom) cannot have multiple lifetime parameters", @@ -103,21 +172,22 @@ fn zf_derive_impl(input: &DeriveInput) -> TokenStream2 { .to_compile_error(); } - let generics_env = typarams.iter().cloned().collect(); - let mut zf_bounds: Vec<WherePredicate> = vec![]; let body = structure.each_variant(|vi| { vi.construct(|f, i| { let binding = format!("__binding_{i}"); let field = Ident::new(&binding, Span::call_site()); - if has_clone_attr(&f.attrs) { + if has_attr(&f.attrs, "clone") { quote! { #field.clone() } } else { + // the field type let fty = replace_lifetime(&f.ty, custom_lt("'zf")); - let lifetime_ty = replace_lifetime(&f.ty, custom_lt("'zf_inner")); + // the corresponding lifetimey type we are borrowing from (effectively, the C type) + let lifetime_ty = + replace_lifetime_and_type(&f.ty, custom_lt("'zf_inner"), &generics_env); let (has_ty, has_lt) = visitor::check_type_for_parameters(&f.ty, &generics_env); if has_ty { @@ -145,12 +215,34 @@ fn zf_derive_impl(input: &DeriveInput) -> TokenStream2 { } }) }); + // Due to the possibility of generics_may_borrow, we might reach here with no lifetimes on self, + // don't accidentally feed them to self later + let (maybe_zf_lifetime, maybe_zf_inner_lifetime) = if lts == 0 { + (quote!(), quote!()) + } else { + (quote!('zf,), quote!('zf_inner,)) + }; + + // Array of C types. Only different if generics are allowed to borrow + let mut typarams_c = typarams.clone(); + + if generics_may_borrow { + for typaram_c in &mut typarams_c { + if let Some(Some(replacement)) = generics_env.get(typaram_c) { + // we use mem::replace here so we can be really clear about the C vs the T type + let typaram_t = mem::replace(typaram_c, replacement.clone()); + zf_bounds + .push(parse_quote!(#typaram_c: zerofrom::ZeroFrom<'zf_inner, #typaram_t>)); + tybounds.push(parse_quote!(#typaram_c)); + } + } + } quote! { - impl<'zf, 'zf_inner, #(#tybounds),*> zerofrom::ZeroFrom<'zf, #name<'zf_inner, #(#typarams),*>> for #name<'zf, #(#typarams),*> + impl<'zf, 'zf_inner, #(#tybounds),*> zerofrom::ZeroFrom<'zf, #name<#maybe_zf_inner_lifetime #(#typarams_c),*>> for #name<#maybe_zf_lifetime #(#typarams),*> where #(#zf_bounds,)* { - fn zero_from(this: &'zf #name<'zf_inner, #(#typarams),*>) -> Self { + fn zero_from(this: &'zf #name<#maybe_zf_inner_lifetime #(#typarams_c),*>) -> Self { match *this { #body } } } @@ -162,8 +254,8 @@ fn custom_lt(s: &str) -> Lifetime { Lifetime::new(s, Span::call_site()) } +/// Replace all lifetimes in a type with a specified one fn replace_lifetime(x: &Type, lt: Lifetime) -> Type { - use syn::fold::Fold; struct ReplaceLifetime(Lifetime); impl Fold for ReplaceLifetime { @@ -173,3 +265,30 @@ fn replace_lifetime(x: &Type, lt: Lifetime) -> Type { } ReplaceLifetime(lt).fold_type(x.clone()) } + +/// Replace all lifetimes in a type with a specified one, AND replace all types that have a corresponding C type +/// with the C type +fn replace_lifetime_and_type( + x: &Type, + lt: Lifetime, + generics_env: &HashMap<Ident, Option<Ident>>, +) -> Type { + struct ReplaceLifetimeAndTy<'a>(Lifetime, &'a HashMap<Ident, Option<Ident>>); + + impl Fold for ReplaceLifetimeAndTy<'_> { + fn fold_lifetime(&mut self, _: Lifetime) -> Lifetime { + self.0.clone() + } + fn fold_type_path(&mut self, i: TypePath) -> TypePath { + if i.qself.is_none() { + if let Some(ident) = i.path.get_ident() { + if let Some(Some(replacement)) = self.1.get(ident) { + return parse_quote!(#replacement); + } + } + } + fold::fold_type_path(self, i) + } + } + ReplaceLifetimeAndTy(lt, generics_env).fold_type(x.clone()) +} diff --git a/vendor/zerofrom-derive/src/visitor.rs b/vendor/zerofrom-derive/src/visitor.rs index ce65f7d6d..4204b7c68 100644 --- a/vendor/zerofrom-derive/src/visitor.rs +++ b/vendor/zerofrom-derive/src/visitor.rs @@ -5,13 +5,13 @@ //! Visitor for determining whether a type has type and non-static lifetime parameters //! (duplicated in yoke/derive/src/visitor.rs) -use std::collections::HashSet; +use std::collections::HashMap; use syn::visit::{visit_lifetime, visit_type, visit_type_path, Visit}; use syn::{Ident, Lifetime, Type, TypePath}; struct TypeVisitor<'a> { /// The type parameters in scope - typarams: &'a HashSet<Ident>, + typarams: &'a HashMap<Ident, Option<Ident>>, /// Whether we found a type parameter found_typarams: bool, /// Whether we found a non-'static lifetime parameter @@ -30,8 +30,11 @@ impl<'a, 'ast> Visit<'ast> for TypeVisitor<'a> { // generics in ty.path because the visitor will eventually visit those // types on its own if let Some(ident) = ty.path.get_ident() { - if self.typarams.contains(ident) { + if let Some(maybe_borrowed) = self.typarams.get(ident) { self.found_typarams = true; + if maybe_borrowed.is_some() { + self.found_lifetimes = true; + } } } @@ -41,7 +44,10 @@ impl<'a, 'ast> Visit<'ast> for TypeVisitor<'a> { /// Checks if a type has type or lifetime parameters, given the local context of /// named type parameters. Returns (has_type_params, has_lifetime_params) -pub fn check_type_for_parameters(ty: &Type, typarams: &HashSet<Ident>) -> (bool, bool) { +pub fn check_type_for_parameters( + ty: &Type, + typarams: &HashMap<Ident, Option<Ident>>, +) -> (bool, bool) { let mut visit = TypeVisitor { typarams, found_typarams: false, @@ -55,14 +61,14 @@ pub fn check_type_for_parameters(ty: &Type, typarams: &HashSet<Ident>) -> (bool, #[cfg(test)] mod tests { use proc_macro2::Span; - use std::collections::HashSet; + use std::collections::HashMap; use syn::{parse_quote, Ident}; use super::check_type_for_parameters; - fn make_typarams(params: &[&str]) -> HashSet<Ident> { + fn make_typarams(params: &[&str]) -> HashMap<Ident, Option<Ident>> { params .iter() - .map(|x| Ident::new(x, Span::call_site())) + .map(|x| (Ident::new(x, Span::call_site()), None)) .collect() } |