Skip to content

Commit

Permalink
Modified system allows template parameters again.
Browse files Browse the repository at this point in the history
  • Loading branch information
someguynamedjosh committed Jun 17, 2023
1 parent 8552835 commit ad3a29d
Show file tree
Hide file tree
Showing 12 changed files with 49 additions and 68 deletions.
36 changes: 18 additions & 18 deletions examples/src/ok_tests.rs
Expand Up @@ -50,24 +50,24 @@ struct AutoDetectCovarianceOnFieldsWithoutThis {
self_reference: &'this (),
}

// /// This test just makes sure that the macro copes with a ton of template parameters being thrown at
// /// it, specifically checking that the templates work fine even when a generated struct doesn't need
// /// all of them. (E.G. heads will only contain 'd, A, and B.)
// #[self_referencing]
// struct TemplateMess<'d, A, B: 'static, C: 'static>
// where
// A: ?Sized,
// B: 'static,
// C: 'static,
// {
// external: &'d A,
// data1: B,
// #[borrows(data1)]
// data2: &'this C,
// data3: B,
// #[borrows(mut data3)]
// data4: &'this mut C,
// }
/// This test just makes sure that the macro copes with a ton of template parameters being thrown at
/// it, specifically checking that the templates work fine even when a generated struct doesn't need
/// all of them. (E.G. heads will only contain 'd, A, and B.)
#[self_referencing]
struct TemplateMess<'d, A, B: 'static, C: 'static>
where
A: ?Sized,
B: 'static,
C: 'static,
{
external: &'d A,
data1: B,
#[borrows(data1)]
data2: &'this C,
data3: B,
#[borrows(mut data3)]
data4: &'this mut C,
}

// /// Regression test for #46
// #[self_referencing]
Expand Down
2 changes: 1 addition & 1 deletion ouroboros/src/lib.rs
Expand Up @@ -351,7 +351,7 @@ pub mod macro_help {
pub extern crate alloc;

pub use aliasable::boxed::AliasableBox;
pub use static_assertions::const_assert_eq;
pub use static_assertions::assert_impl_all;
use aliasable::boxed::UniqueBox;

pub struct CheckIfTypeIsStd<T>(core::marker::PhantomData<T>);
Expand Down
16 changes: 5 additions & 11 deletions ouroboros_macro/src/generate/constructor.rs
Expand Up @@ -159,19 +159,13 @@ pub fn create_builder_and_constructor(
let constructor_def = quote! {
#documentation
#vis #constructor_fn(#(#params),*) -> #struct_name <#(#generic_args),*> {
::ouroboros::macro_help::const_assert_eq!(
::core::mem::size_of::<#struct_name<#(#generic_args_with_static_lifetimes),*>>(),
::core::mem::size_of::<#internal_ident<#(#generic_args_with_static_lifetimes),*>>()
);
::ouroboros::macro_help::const_assert_eq!(
::core::mem::align_of::<#struct_name<#(#generic_args_with_static_lifetimes),*>>(),
::core::mem::align_of::<#internal_ident<#(#generic_args_with_static_lifetimes),*>>()
);
#(#code)*
unsafe {
::core::mem::transmute(#internal_ident::<#(#generic_args),*> {
#(#field_names),*
})
Self {
actual_data: ::core::mem::MaybeUninit::new(#internal_ident {
#(#field_names),*
})
}
}
}
};
Expand Down
5 changes: 1 addition & 4 deletions ouroboros_macro/src/generate/drop.rs
Expand Up @@ -5,7 +5,6 @@ use syn::Error;

pub fn create_drop_impl(info: &StructInfo) -> Result<TokenStream, Error> {
let ident = &info.ident;
let internal_ident = &info.internal_ident;
let generics = &info.generics;
let generic_args = info.generic_arguments();

Expand All @@ -16,9 +15,7 @@ pub fn create_drop_impl(info: &StructInfo) -> Result<TokenStream, Error> {
Ok(quote! {
impl #generics ::core::ops::Drop for #ident<#(#generic_args,)*> #where_clause {
fn drop(&mut self) {
unsafe {
::core::ptr::drop_in_place(::core::mem::transmute::<_, *mut #internal_ident <#(#generic_args,)*>>(self));
}
unsafe { self.actual_data.assume_init_drop() };
}
}
})
Expand Down
4 changes: 3 additions & 1 deletion ouroboros_macro/src/generate/into_heads.rs
Expand Up @@ -72,7 +72,9 @@ pub fn make_into_heads(info: &StructInfo, options: Options) -> (TokenStream, Tok
#[allow(clippy::drop_copy)]
#[allow(clippy::drop_non_drop)]
#visibility fn into_heads(self) -> Heads<#(#generic_args),*> {
let this: #internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute(self) };
let this_ptr = &self as *const _;
let this: #internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute_copy(&*this_ptr) };
::core::mem::forget(self);
#(#code)*
Heads {
#(#field_initializers),*
Expand Down
7 changes: 3 additions & 4 deletions ouroboros_macro/src/generate/struc.rs
Expand Up @@ -14,15 +14,14 @@ pub fn create_actual_struct_def(info: &StructInfo) -> Result<TokenStream, Error>
fields.push(quote! { #ident: ::core::marker::PhantomData<#ty> });
}
let generic_params = info.generic_params();
let generic_args = info.generic_arguments_with_static_lifetimes();
let generic_args = info.generic_arguments();
let generic_where = &info.generics.where_clause;
let ident = &info.ident;
let internal_ident = &info.internal_ident;
Ok(quote! {
#[repr(transparent)]
#visibility struct #ident <#generic_params> #generic_where {
actual_data: ::core::mem::MaybeUninit<[u8; ::core::mem::size_of::<#internal_ident<#(#generic_args),*>>()]>,
_alignment: [#internal_ident<#(#generic_args),*>; 0],
#(#fields),*
actual_data: ::core::mem::MaybeUninit<#internal_ident<#(#generic_args),*>>,
}
})
}
Expand Down
6 changes: 5 additions & 1 deletion ouroboros_macro/src/generate/try_constructor.rs
Expand Up @@ -233,7 +233,11 @@ pub fn create_try_builder_and_constructor(
#visibility #or_recover_constructor_fn<Error_>(#(#params),*) -> ::core::result::Result<#struct_name <#(#generic_args),*>, (Error_, Heads<#(#generic_args),*>)> {
#(#or_recover_code)*
::core::result::Result::Ok(unsafe {
::core::mem::transmute(#internal_ident { #(#field_names),* })
Self {
actual_data: ::core::mem::MaybeUninit::new(#internal_ident {
#(#field_names),*
})
}
})
}
};
Expand Down
5 changes: 2 additions & 3 deletions ouroboros_macro/src/generate/with_all.rs
Expand Up @@ -109,15 +109,14 @@ pub fn make_with_all_function(
} else {
quote! { #[doc(hidden)] }
};
let generic_args = info.generic_arguments();
let fn_defs = quote! {
#documentation
#[inline(always)]
#visibility fn with <'outer_borrow, ReturnType>(
&'outer_borrow self,
user: impl for<'this> ::core::ops::FnOnce(#borrowed_fields_type) -> ReturnType
) -> ReturnType {
let this: &#internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute(self) };
let this = unsafe { self.actual_data.assume_init_ref() };
user(BorrowedFields {
#(#field_assignments),*
})
Expand All @@ -128,7 +127,7 @@ pub fn make_with_all_function(
&'outer_borrow mut self,
user: impl for<'this> ::core::ops::FnOnce(#borrowed_mut_fields_type) -> ReturnType
) -> ReturnType {
let this: &mut #internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute(self) };
let this = unsafe { self.actual_data.assume_init_mut() };
user(BorrowedMutFields {
#(#mut_field_assignments),*
})
Expand Down
18 changes: 8 additions & 10 deletions ouroboros_macro/src/generate/with_each.rs
Expand Up @@ -36,8 +36,8 @@ pub fn make_with_functions(info: &StructInfo, options: Options) -> Result<Vec<To
&'outer_borrow self,
user: impl for<'this> ::core::ops::FnOnce(&'outer_borrow #field_type) -> ReturnType,
) -> ReturnType {
let this: &#internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute(self) };
user(&this. #field_name)
let field = &unsafe { self.actual_data.assume_init_ref() }.#field_name;
user(field)
}
});
if field.covariant == Some(true) {
Expand All @@ -48,8 +48,7 @@ pub fn make_with_functions(info: &StructInfo, options: Options) -> Result<Vec<To
#visibility fn #borrower_name<'this>(
&'this self,
) -> &'this #field_type {
let this: &#internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute(self) };
&this.#field_name
&unsafe { self.actual_data.assume_init_ref() }.#field_name
}
});
} else if field.covariant.is_none() {
Expand Down Expand Up @@ -80,8 +79,8 @@ pub fn make_with_functions(info: &StructInfo, options: Options) -> Result<Vec<To
&'outer_borrow mut self,
user: impl for<'this> ::core::ops::FnOnce(&'outer_borrow mut #field_type) -> ReturnType,
) -> ReturnType {
let this: &mut #internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute(self) };
user(&mut this. #field_name)
let field = &mut unsafe { self.actual_data.assume_init_mut() }.#field_name;
user(field)
}
});
} else if field.field_type == FieldType::Borrowed {
Expand All @@ -107,8 +106,8 @@ pub fn make_with_functions(info: &StructInfo, options: Options) -> Result<Vec<To
&'outer_borrow self,
user: impl for<'this> ::core::ops::FnOnce(&'outer_borrow #field_type) -> ReturnType,
) -> ReturnType {
let this: &#internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute(self) };
user(&*this.#field_name)
let field = &unsafe { self.actual_data.assume_init_ref() }.#field_name;
user(field)
}
});
if field.self_referencing {
Expand All @@ -126,8 +125,7 @@ pub fn make_with_functions(info: &StructInfo, options: Options) -> Result<Vec<To
#visibility fn #borrower_name<'this>(
&'this self,
) -> &'this #field_type {
let this: &#internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute(self) };
&*this.#field_name
&unsafe { self.actual_data.assume_init_ref() }.#field_name
}
});
} else if field.field_type == FieldType::BorrowedMut {
Expand Down
2 changes: 1 addition & 1 deletion ouroboros_macro/src/info_structures.rs
Expand Up @@ -3,7 +3,7 @@ use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote, ToTokens};
use syn::{
punctuated::Punctuated, token::Comma, Attribute, ConstParam, Error, GenericParam, Generics,
LifetimeParam, Type, TypeParam, Visibility,
LifetimeParam, Type, TypeParam, Visibility, WhereClause,
};

#[derive(Clone, Copy)]
Expand Down
4 changes: 2 additions & 2 deletions ouroboros_macro/src/lib.rs
Expand Up @@ -17,15 +17,15 @@ use crate::{
info_structures::Options,
parse::parse_struct,
};
use generate::{drop::create_drop_impl, struc::create_actual_struct_def};
use heck::ToSnakeCase;
use generate::{struc::create_actual_struct_def, drop::create_drop_impl};
use info_structures::BuilderType;
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use proc_macro2::TokenTree;
use proc_macro_error::proc_macro_error;
use quote::{format_ident, quote};
use syn::{Error, ItemStruct};
use syn::{parse_quote, punctuated::Punctuated, token::Where, Error, ItemStruct, WhereClause};

fn self_referencing_impl(
original_struct_def: &ItemStruct,
Expand Down
12 changes: 0 additions & 12 deletions ouroboros_macro/src/parse.rs
Expand Up @@ -138,18 +138,6 @@ fn parse_derive_attribute(attr: &Attribute) -> Result<Vec<Derive>, Error> {
pub fn parse_struct(def: &ItemStruct) -> Result<StructInfo, Error> {
let vis = def.vis.clone();
let generics = def.generics.clone();
if let Some(first_param) = generics.type_params().next() {
return Err(Error::new(
first_param.span(),
"Self-referencing structs currently cannot have type or constant parameters, only lifetime parameters.",
));
}
if let Some(first_param) = generics.const_params().next() {
return Err(Error::new(
first_param.span(),
"Self-referencing structs currently cannot have type or constant parameters, only lifetime parameters.",
));
}
let mut actual_struct_def = def.clone();
actual_struct_def.vis = vis.clone();
let mut fields = Vec::new();
Expand Down

0 comments on commit ad3a29d

Please sign in to comment.