summaryrefslogtreecommitdiffstats
path: root/vendor/zerofrom-derive
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/zerofrom-derive')
-rw-r--r--vendor/zerofrom-derive/.cargo-checksum.json2
-rw-r--r--vendor/zerofrom-derive/Cargo.lock115
-rw-r--r--vendor/zerofrom-derive/Cargo.toml19
-rw-r--r--vendor/zerofrom-derive/LICENSE79
-rw-r--r--vendor/zerofrom-derive/README.md4
-rw-r--r--vendor/zerofrom-derive/examples/zf_derive.rs24
-rw-r--r--vendor/zerofrom-derive/src/lib.rs149
-rw-r--r--vendor/zerofrom-derive/src/visitor.rs20
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(&param.attrs, "may_borrow")
+ || may_borrow_attrs.contains(&param.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()
}