From 149c2ebabfdb971ee6faa8e3e5d087e23d71ff46 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Wed, 6 Mar 2024 23:23:26 +0100 Subject: [PATCH 1/2] Require Sized generics in Yokeable derive --- utils/yoke/derive/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utils/yoke/derive/src/lib.rs b/utils/yoke/derive/src/lib.rs index dd1ea90b8d7..57d8d38b206 100644 --- a/utils/yoke/derive/src/lib.rs +++ b/utils/yoke/derive/src/lib.rs @@ -53,7 +53,10 @@ fn yokeable_derive_impl(input: &DeriveInput) -> TokenStream2 { // the Yokeable impl becomes really unweildy to generate safely let static_bounds: Vec = typarams .iter() - .map(|ty| parse_quote!(#ty: 'static)) + // Yokeable::Output is Sized, so we ask that our generics are Sized, too. + // This could be improved to only enforce Sized on the type parameter that + // makes this struct a DST (the last field in the struct). + .map(|ty| parse_quote!(#ty: 'static + Sized)) .collect(); let lts = input.generics.lifetimes().count(); if lts == 0 { From e0722be3eb48becbe5a43061f8ed6b18feb42b42 Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Thu, 7 Mar 2024 11:40:11 +0100 Subject: [PATCH 2/2] Review feedback --- utils/yoke/derive/examples/yoke_derive.rs | 24 ++++++++++++++++++++++- utils/yoke/derive/src/lib.rs | 9 +++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/utils/yoke/derive/examples/yoke_derive.rs b/utils/yoke/derive/examples/yoke_derive.rs index a011d5c2411..d65ada1bc92 100644 --- a/utils/yoke/derive/examples/yoke_derive.rs +++ b/utils/yoke/derive/examples/yoke_derive.rs @@ -4,7 +4,7 @@ #![allow(unused)] -use std::borrow::Cow; +use std::{borrow::Cow, marker::PhantomData}; use yoke::{Yoke, Yokeable}; use zerovec::{maps::ZeroMapKV, ule::AsULE, VarZeroVec, ZeroMap, ZeroVec}; @@ -67,6 +67,25 @@ pub struct ZeroMapGenericExample<'a, T: for<'b> ZeroMapKV<'b> + ?Sized> { map: ZeroMap<'a, str, T>, } +#[derive(Yokeable)] +pub struct MaybeSizedWrap { + x: T, + y: Option, + ignored: PhantomData, + q: Q, +} + +// TODO(#4119): Make this example compile +/* +#[derive(Yokeable)] +pub struct MaybeSizedWrapWithLifetime<'a, T, Q: ?Sized, U: ?Sized> { + x: T, + y: Option, + ignored: &'a U, + q: Q, +} +*/ + pub struct AssertYokeable { string: Yoke>, int: Yoke>, @@ -81,6 +100,9 @@ pub struct AssertYokeable { map: Yoke, Box<[u8]>>, map_gen1: Yoke, Box<[u8]>>, map_gen2: Yoke, Box<[u8]>>, + maybe_sized_wrap: Yoke, Box<[u8]>>, + // TODO(#4119): Make this example compile + // maybe_sized_wrap_with_lt: Yoke, Box<[u8]>>, } fn main() {} diff --git a/utils/yoke/derive/src/lib.rs b/utils/yoke/derive/src/lib.rs index 57d8d38b206..4d3d8843a4f 100644 --- a/utils/yoke/derive/src/lib.rs +++ b/utils/yoke/derive/src/lib.rs @@ -53,17 +53,14 @@ fn yokeable_derive_impl(input: &DeriveInput) -> TokenStream2 { // the Yokeable impl becomes really unweildy to generate safely let static_bounds: Vec = typarams .iter() - // Yokeable::Output is Sized, so we ask that our generics are Sized, too. - // This could be improved to only enforce Sized on the type parameter that - // makes this struct a DST (the last field in the struct). - .map(|ty| parse_quote!(#ty: 'static + Sized)) + .map(|ty| parse_quote!(#ty: 'static)) .collect(); let lts = input.generics.lifetimes().count(); if lts == 0 { let name = &input.ident; quote! { // This is safe because there are no lifetime parameters. - unsafe impl<'a, #(#tybounds),*> yoke::Yokeable<'a> for #name<#(#typarams),*> where #(#static_bounds),* { + unsafe impl<'a, #(#tybounds),*> yoke::Yokeable<'a> for #name<#(#typarams),*> where #(#static_bounds,)* Self: Sized { type Output = Self; #[inline] fn transform(&self) -> &Self::Output { @@ -223,7 +220,7 @@ fn yokeable_derive_impl(input: &DeriveInput) -> TokenStream2 { // // This custom derive can be improved to handle this case when // necessary - unsafe impl<'a, #(#tybounds),*> yoke::Yokeable<'a> for #name<'static, #(#typarams),*> where #(#static_bounds),* { + unsafe impl<'a, #(#tybounds),*> yoke::Yokeable<'a> for #name<'static, #(#typarams),*> where #(#static_bounds,)* { type Output = #name<'a, #(#typarams),*>; #[inline] fn transform(&'a self) -> &'a Self::Output {