From 71de8eb50cd9cab027f85fae7ce8caa04584aab5 Mon Sep 17 00:00:00 2001 From: joshua-maros <60271685+joshua-maros@users.noreply.github.com> Date: Sun, 11 Jun 2023 18:24:07 -0500 Subject: [PATCH] Revert "Blah." This reverts commit 30637694c97b231196e133b92da6a84336ee1216. --- examples/src/ok_tests.rs | 92 +++++++++++---------- ouroboros_macro/src/generate/constructor.rs | 11 ++- ouroboros_macro/src/generate/drop.rs | 28 ------- ouroboros_macro/src/generate/into_heads.rs | 2 +- ouroboros_macro/src/generate/mod.rs | 1 - ouroboros_macro/src/generate/struc.rs | 6 +- ouroboros_macro/src/info_structures.rs | 24 +----- ouroboros_macro/src/lib.rs | 4 +- ouroboros_macro/src/parse.rs | 12 --- ouroboros_macro/src/utils.rs | 4 +- 10 files changed, 61 insertions(+), 123 deletions(-) delete mode 100644 ouroboros_macro/src/generate/drop.rs diff --git a/examples/src/ok_tests.rs b/examples/src/ok_tests.rs index 7a08614..db27303 100644 --- a/examples/src/ok_tests.rs +++ b/examples/src/ok_tests.rs @@ -1,5 +1,9 @@ +use alloc::borrow::ToOwned; use alloc::boxed::Box; +use alloc::vec; +use alloc::vec::Vec; use core::fmt::Debug; +use ouroboros::macro_help::AliasableBox; use ouroboros::self_referencing; @@ -50,32 +54,32 @@ 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] -// struct PreviouslyBrokeAutoGeneratedChecker { -// x: T, -// #[borrows(mut x)] -// y: &'this (), -// } +/// Regression test for #46 +#[self_referencing] +struct PreviouslyBrokeAutoGeneratedChecker { + x: T, + #[borrows(mut x)] + y: &'this (), +} #[test] fn box_and_ref() { @@ -200,25 +204,25 @@ fn box_and_mut_ref() { assert!(bar.with_dref(|dref| **dref) == 34); } -// #[test] -// fn template_mess() { -// let ext_str = "Hello World!".to_owned(); -// let mut instance = TemplateMessBuilder { -// external: &ext_str[..], -// data1: "asdf".to_owned(), -// data2_builder: |data1_contents| data1_contents, -// data3: "asdf".to_owned(), -// data4_builder: |data3_contents| data3_contents, -// } -// .build(); -// instance.with_external(|ext| assert_eq!(*ext, "Hello World!")); -// instance.with_data1(|data| assert_eq!(data, "asdf")); -// instance.with_data4_mut(|con| **con = "Modified".to_owned()); -// instance.with(|fields| { -// assert!(**fields.data1 == **fields.data2); -// assert!(*fields.data4 == "Modified"); -// }); -// } +#[test] +fn template_mess() { + let ext_str = "Hello World!".to_owned(); + let mut instance = TemplateMessBuilder { + external: &ext_str[..], + data1: "asdf".to_owned(), + data2_builder: |data1_contents| data1_contents, + data3: "asdf".to_owned(), + data4_builder: |data3_contents| data3_contents, + } + .build(); + instance.with_external(|ext| assert_eq!(*ext, "Hello World!")); + instance.with_data1(|data| assert_eq!(data, "asdf")); + instance.with_data4_mut(|con| **con = "Modified".to_owned()); + instance.with(|fields| { + assert!(**fields.data1 == **fields.data2); + assert!(*fields.data4 == "Modified"); + }); +} const STATIC_INT: i32 = 456; #[test] diff --git a/ouroboros_macro/src/generate/constructor.rs b/ouroboros_macro/src/generate/constructor.rs index 60583d8..2ece184 100644 --- a/ouroboros_macro/src/generate/constructor.rs +++ b/ouroboros_macro/src/generate/constructor.rs @@ -13,7 +13,6 @@ pub fn create_builder_and_constructor( ) -> Result<(Ident, TokenStream, TokenStream), Error> { let struct_name = info.ident.clone(); let generic_args = info.generic_arguments(); - let generic_args_with_static_lifetimes = info.generic_arguments_with_static_lifetimes(); let vis = if options.do_pub_extras { info.vis.clone() @@ -160,16 +159,16 @@ pub fn create_builder_and_constructor( #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),*>>() + ::core::mem::size_of::<#struct_name<#(#generic_args),*>>(), + ::core::mem::size_of::<#internal_ident<#(#generic_args),*>>() ); ::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),*>>() + ::core::mem::align_of::<#struct_name<#(#generic_args),*>>(), + ::core::mem::align_of::<#internal_ident<#(#generic_args),*>>() ); #(#code)* unsafe { - ::core::mem::transmute(#internal_ident::<#(#generic_args),*> { + ::core::mem::transmute(#internal_ident<#(#generic_args),*> { #(#field_names),* }) } diff --git a/ouroboros_macro/src/generate/drop.rs b/ouroboros_macro/src/generate/drop.rs deleted file mode 100644 index a78d5e1..0000000 --- a/ouroboros_macro/src/generate/drop.rs +++ /dev/null @@ -1,28 +0,0 @@ -use crate::{ - info_structures::StructInfo, - utils::{self, replace_this_with_lifetime}, -}; -use proc_macro2::TokenStream; -use quote::quote; -use syn::Error; - -pub fn create_drop_impl(info: &StructInfo) -> Result { - let ident = &info.ident; - let internal_ident = &info.internal_ident; - let generics = &info.generics; - let generic_args = info.generic_arguments(); - - let mut where_clause = quote! {}; - if let Some(clause) = &generics.where_clause { - where_clause = quote! { #clause }; - } - 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)); - } - } - } - }) -} diff --git a/ouroboros_macro/src/generate/into_heads.rs b/ouroboros_macro/src/generate/into_heads.rs index 2acb67d..12016a8 100644 --- a/ouroboros_macro/src/generate/into_heads.rs +++ b/ouroboros_macro/src/generate/into_heads.rs @@ -1,5 +1,5 @@ use proc_macro2::TokenStream; -use quote::quote; +use quote::{format_ident, quote}; use crate::info_structures::{Options, StructInfo}; diff --git a/ouroboros_macro/src/generate/mod.rs b/ouroboros_macro/src/generate/mod.rs index 4ba6a3e..0b229d1 100644 --- a/ouroboros_macro/src/generate/mod.rs +++ b/ouroboros_macro/src/generate/mod.rs @@ -1,6 +1,5 @@ pub mod constructor; pub mod derives; -pub mod drop; pub mod into_heads; pub mod struc; pub mod summon_checker; diff --git a/ouroboros_macro/src/generate/struc.rs b/ouroboros_macro/src/generate/struc.rs index 28f6197..8a7b9f4 100644 --- a/ouroboros_macro/src/generate/struc.rs +++ b/ouroboros_macro/src/generate/struc.rs @@ -14,7 +14,7 @@ pub fn create_actual_struct_def(info: &StructInfo) -> Result 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; @@ -22,7 +22,6 @@ pub fn create_actual_struct_def(info: &StructInfo) -> Result #visibility struct #ident <#generic_params> #generic_where { actual_data: [u8; ::core::mem::size_of::<#internal_ident<#(#generic_args),*>>()], _alignment: [#internal_ident<#(#generic_args),*>; 0], - #(#fields),* } }) } @@ -34,6 +33,7 @@ pub fn create_actual_struct_def(info: &StructInfo) -> Result /// but references *created* inside a function can be considered invalid /// whenever, even during the duration of the function.) pub fn create_internal_struct_def(info: &StructInfo) -> Result { + let vis = quote! { pub(super) }; let ident = &info.internal_ident; let generics = &info.generics; @@ -60,7 +60,7 @@ pub fn create_internal_struct_def(info: &StructInfo) -> Result Vec<&GenericParam> { - self.generics - .params - .iter() - .filter(|p| { - if let GenericParam::Lifetime(..) = p { - false - } else { - true - } - }) - .collect() - } - /// Same as generic_params but with 'this and 'outer_borrow prepended. pub fn borrowed_generic_params(&self) -> TokenStream { if self.generic_params().is_empty() { @@ -129,15 +115,7 @@ impl StructInfo { } pub fn generic_arguments(&self) -> Vec { - make_generic_arguments(self.generics.params.iter().collect()) - } - - pub fn generic_arguments_with_static_lifetimes(&self) -> Vec { - let mut result = make_generic_arguments(self.generic_params_without_lifetimes()); - for _ in 0..self.generics.lifetimes().count() { - result.insert(0, quote! { 'static }); - } - result + make_generic_arguments(&self.generics) } /// Same as generic_arguments but with 'outer_borrow and 'this prepended. diff --git a/ouroboros_macro/src/lib.rs b/ouroboros_macro/src/lib.rs index c46584c..d0a6898 100644 --- a/ouroboros_macro/src/lib.rs +++ b/ouroboros_macro/src/lib.rs @@ -17,7 +17,7 @@ use crate::{ info_structures::Options, parse::parse_struct, }; -use generate::{struc::create_actual_struct_def, drop::create_drop_impl}; +use generate::struc::create_actual_struct_def; use inflector::Inflector; use info_structures::BuilderType; use proc_macro::TokenStream; @@ -39,7 +39,6 @@ fn self_referencing_impl( let actual_struct_def = create_actual_struct_def(&info)?; let internal_struct_def = create_internal_struct_def(&info)?; - let drop_impl = create_drop_impl(&info)?; let borrowchk_summoner = generate_checker_summoner(&info)?; @@ -82,7 +81,6 @@ fn self_referencing_impl( #[doc="The self-referencing struct."] #actual_struct_def #internal_struct_def - #drop_impl #borrowchk_summoner #builder_def #async_builder_def diff --git a/ouroboros_macro/src/parse.rs b/ouroboros_macro/src/parse.rs index a01d9a8..8d5fd1a 100644 --- a/ouroboros_macro/src/parse.rs +++ b/ouroboros_macro/src/parse.rs @@ -133,18 +133,6 @@ fn parse_derive_attribute(attr: &Attribute) -> Result, Error> { pub fn parse_struct(def: &ItemStruct) -> Result { 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(); diff --git a/ouroboros_macro/src/utils.rs b/ouroboros_macro/src/utils.rs index 3b1f770..5bbae6c 100644 --- a/ouroboros_macro/src/utils.rs +++ b/ouroboros_macro/src/utils.rs @@ -33,9 +33,9 @@ pub fn make_generic_consumers(generics: &Generics) -> impl Iterator) -> Vec { +pub fn make_generic_arguments(generics: &Generics) -> Vec { let mut arguments = Vec::new(); - for generic in generics { + for generic in generics.params.clone() { match generic { GenericParam::Type(typ) => { let ident = &typ.ident;