diff --git a/examples/tests/conversion.rs b/examples/tests/conversion.rs index fd48ec4f..b5814212 100644 --- a/examples/tests/conversion.rs +++ b/examples/tests/conversion.rs @@ -38,7 +38,7 @@ mod receiver { impl From<&X> for Y { fn from(_: &X) -> Self { - Y + Self } } @@ -66,6 +66,36 @@ mod receiver { } } +mod lifetime { + use serde::{Deserialize, Serialize}; + + #[derive(Clone)] + struct X<'a>(&'a bool); + + #[derive(Clone, Deserialize, Serialize)] + struct Y(bool); + + impl<'a> From> for Y { + fn from(x: X) -> Self { + Self(*x.0) + } + } + + impl test_fuzz::Into> for Y { + fn into(self) -> X<'static> { + X(Box::leak(Box::new(self.0))) + } + } + + #[test_fuzz::test_fuzz(convert = "X<'a>, Y")] + fn target<'a>(x: X<'a>) {} + + #[test] + fn test() { + target(X(&false)); + } +} + #[cfg(feature = "__inapplicable_conversion")] mod inapplicable_conversion { use serde::{Deserialize, Serialize}; @@ -81,7 +111,7 @@ mod inapplicable_conversion { impl From for Z { fn from(_: Y) -> Self { - Z + Self } } diff --git a/macro/src/lib.rs b/macro/src/lib.rs index 99166354..6c4d6862 100644 --- a/macro/src/lib.rs +++ b/macro/src/lib.rs @@ -19,9 +19,9 @@ use subprocess::{Exec, Redirection}; use syn::{ parse::Parser, parse_macro_input, parse_quote, parse_str, punctuated::Punctuated, token, Attribute, AttributeArgs, Block, Expr, FnArg, GenericArgument, GenericParam, Generics, Ident, - ImplItem, ImplItemMethod, ItemFn, ItemImpl, ItemMod, PatType, Path, PathArguments, PathSegment, - Receiver, ReturnType, Signature, Stmt, Type, TypeParam, TypePath, TypeReference, TypeSlice, - Visibility, WhereClause, WherePredicate, + ImplItem, ImplItemMethod, ItemFn, ItemImpl, ItemMod, LifetimeDef, PatType, Path, PathArguments, + PathSegment, Receiver, ReturnType, Signature, Stmt, Type, TypeParam, TypePath, TypeReference, + TypeSlice, Visibility, WhereClause, WherePredicate, }; use toolchain_find::find_installed_component; use unzip_n::unzip_n; @@ -1008,12 +1008,14 @@ fn type_generic_phantom_types(generics: &Generics) -> Vec { generics .params .iter() - .filter_map(|param| { - if let GenericParam::Type(TypeParam { ident, .. }) = param { + .filter_map(|param| match param { + GenericParam::Type(TypeParam { ident, .. }) => { Some(parse_quote! { std::marker::PhantomData< #ident > }) - } else { - None } + GenericParam::Lifetime(LifetimeDef { lifetime, .. }) => { + Some(parse_quote! { std::marker::PhantomData< & #lifetime () > }) + } + GenericParam::Const(_) => None, }) .collect() }