From b4d49cd874cfc74a3e6c496c61eaacf599330fa0 Mon Sep 17 00:00:00 2001 From: joshua-maros <60271685+joshua-maros@users.noreply.github.com> Date: Sat, 13 May 2023 19:28:37 -0700 Subject: [PATCH] Revert "Failed attempt to fix problems." This reverts commit d6eaf95a995431c6eeb525d6dfa9c96e411779c7. --- examples/Cargo.toml | 4 +-- examples/src/ok_tests.rs | 3 -- ouroboros/Cargo.toml | 5 ++- ouroboros/src/lib.rs | 1 - ouroboros_macro/Cargo.toml | 2 +- ouroboros_macro/src/generate/constructor.rs | 15 ++------- ouroboros_macro/src/generate/into_heads.rs | 14 ++++----- ouroboros_macro/src/generate/struc.rs | 31 +++---------------- .../src/generate/try_constructor.rs | 5 +-- ouroboros_macro/src/generate/with_all.rs | 10 ++---- ouroboros_macro/src/generate/with_each.rs | 17 +++------- ouroboros_macro/src/info_structures.rs | 11 ------- ouroboros_macro/src/lib.rs | 5 +-- ouroboros_macro/src/parse.rs | 1 - 14 files changed, 27 insertions(+), 97 deletions(-) diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 8243ddf..e8fa0fd 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ouroboros_examples" -version = "0.16.0" +version = "0.15.7" authors = ["Joshua Maros "] edition = "2018" license = "MIT OR Apache-2.0" @@ -21,7 +21,7 @@ std = [] __tokio = ["tokio", "std"] [dependencies] -ouroboros = { version = "0.16.0", path = "../ouroboros" } +ouroboros = { version = "0.15.7", path = "../ouroboros" } tokio = { version = "1.27.0", features = [ "macros", "rt" ], optional = true } [dev-dependencies] diff --git a/examples/src/ok_tests.rs b/examples/src/ok_tests.rs index db27303..61ae346 100644 --- a/examples/src/ok_tests.rs +++ b/examples/src/ok_tests.rs @@ -1,9 +1,6 @@ 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; diff --git a/ouroboros/Cargo.toml b/ouroboros/Cargo.toml index 3c256b4..4ee1ca3 100644 --- a/ouroboros/Cargo.toml +++ b/ouroboros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ouroboros" -version = "0.16.0" +version = "0.15.7" authors = ["Joshua Maros "] edition = "2018" license = "MIT OR Apache-2.0" @@ -11,8 +11,7 @@ repository = "https://github.com/joshua-maros/ouroboros" [dependencies] aliasable = "0.1.3" -ouroboros_macro = { version = "0.16.0", path = "../ouroboros_macro" } -static_assertions = "1.1.0" +ouroboros_macro = { version = "0.15.7", path = "../ouroboros_macro" } [features] default = ["std"] diff --git a/ouroboros/src/lib.rs b/ouroboros/src/lib.rs index 13870da..efd32e8 100644 --- a/ouroboros/src/lib.rs +++ b/ouroboros/src/lib.rs @@ -351,7 +351,6 @@ pub mod macro_help { pub extern crate alloc; pub use aliasable::boxed::AliasableBox; - pub use static_assertions::const_assert_eq; use aliasable::boxed::UniqueBox; pub struct CheckIfTypeIsStd(core::marker::PhantomData); diff --git a/ouroboros_macro/Cargo.toml b/ouroboros_macro/Cargo.toml index 5b2a56b..a350e81 100644 --- a/ouroboros_macro/Cargo.toml +++ b/ouroboros_macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ouroboros_macro" -version = "0.16.0" +version = "0.15.7" authors = ["Joshua Maros "] edition = "2018" license = "MIT OR Apache-2.0" diff --git a/ouroboros_macro/src/generate/constructor.rs b/ouroboros_macro/src/generate/constructor.rs index 2ece184..6ab47bc 100644 --- a/ouroboros_macro/src/generate/constructor.rs +++ b/ouroboros_macro/src/generate/constructor.rs @@ -154,23 +154,12 @@ pub fn create_builder_and_constructor( BuilderType::Sync => quote! { fn new }, }; let field_names: Vec<_> = info.fields.iter().map(|field| field.name.clone()).collect(); - let internal_ident = &info.internal_ident; 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),*>>(), - ::core::mem::size_of::<#internal_ident<#(#generic_args),*>>() - ); - ::ouroboros::macro_help::const_assert_eq!( - ::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),*> { - #(#field_names),* - }) + Self { + #(#field_names),* } } }; diff --git a/ouroboros_macro/src/generate/into_heads.rs b/ouroboros_macro/src/generate/into_heads.rs index 12016a8..5784e46 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::{format_ident, quote}; +use quote::quote; use crate::info_structures::{Options, StructInfo}; @@ -13,16 +13,12 @@ pub fn make_into_heads(info: &StructInfo, options: Options) -> (TokenStream, Tok let mut code = Vec::new(); let mut field_initializers = Vec::new(); let mut head_fields = Vec::new(); - let internal_struct = &info.internal_ident; // Drop everything in the reverse order of what it was declared in. Fields that come later // are only dependent on fields that came before them. for field in info.fields.iter().rev() { let field_name = &field.name; - if field.self_referencing { - // Heads are fields that do not borrow anything. - code.push(quote! { ::core::mem::drop(this.#field_name); }); - } else { - code.push(quote! { let #field_name = this.#field_name; }); + if !field.self_referencing { + code.push(quote! { let #field_name = self.#field_name; }); if field.is_borrowed() { field_initializers .push(quote! { #field_name: ::ouroboros::macro_help::unbox(#field_name) }); @@ -31,6 +27,9 @@ pub fn make_into_heads(info: &StructInfo, options: Options) -> (TokenStream, Tok } let field_type = &field.typ; head_fields.push(quote! { #visibility #field_name: #field_type }); + } else { + // Heads are fields that do not borrow anything. + code.push(quote! { ::core::mem::drop(self.#field_name); }); } } for (ty, ident) in info.generic_consumers() { @@ -72,7 +71,6 @@ 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) }; #(#code)* Heads { #(#field_initializers),* diff --git a/ouroboros_macro/src/generate/struc.rs b/ouroboros_macro/src/generate/struc.rs index 8a7b9f4..9b2ff51 100644 --- a/ouroboros_macro/src/generate/struc.rs +++ b/ouroboros_macro/src/generate/struc.rs @@ -6,35 +6,12 @@ use proc_macro2::TokenStream; use quote::quote; use syn::Error; -/// Creates the struct that will actually store the data. +/// Creates the struct that will actually store the data. This involves properly organizing the +/// fields, collecting metadata about them, reversing the order everything is stored in, and +/// converting any uses of 'this to 'static. pub fn create_actual_struct_def(info: &StructInfo) -> Result { - let visibility = utils::submodule_contents_visiblity(&info.vis); - let mut fields = Vec::new(); - for (ty, ident) in info.generic_consumers() { - fields.push(quote! { #ident: ::core::marker::PhantomData<#ty> }); - } - let generic_params = info.generic_params(); - let generic_args = info.generic_arguments(); - let generic_where = &info.generics.where_clause; + let vis = utils::submodule_contents_visiblity(&info.vis); let ident = &info.ident; - let internal_ident = &info.internal_ident; - Ok(quote! { - #visibility struct #ident <#generic_params> #generic_where { - actual_data: [u8; ::core::mem::size_of::<#internal_ident<#(#generic_args),*>>()], - _alignment: [#internal_ident<#(#generic_args),*>; 0], - } - }) -} - -/// Creates a struct with fields like the original struct. Instances of the -/// "actual" struct are reinterpreted as instances of the "internal" struct -/// whenever data needs to be accessed. (This gets around the problem that -/// references passed to functions must be valid through the entire function, -/// 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; let field_defs: Vec<_> = info diff --git a/ouroboros_macro/src/generate/try_constructor.rs b/ouroboros_macro/src/generate/try_constructor.rs index a5469d6..4078c56 100644 --- a/ouroboros_macro/src/generate/try_constructor.rs +++ b/ouroboros_macro/src/generate/try_constructor.rs @@ -223,7 +223,6 @@ pub fn create_try_builder_and_constructor( quote! { #struct_name::#or_recover_ident(#(#builder_struct_field_names),*).map_err(|(error, _heads)| error) } }; let field_names: Vec<_> = info.fields.iter().map(|field| field.name.clone()).collect(); - let internal_ident = &info.internal_ident; let constructor_def = quote! { #documentation #visibility #constructor_fn(#(#params),*) -> ::core::result::Result<#struct_name <#(#generic_args),*>, Error_> { @@ -232,9 +231,7 @@ pub fn create_try_builder_and_constructor( #or_recover_documentation #visibility #or_recover_constructor_fn(#(#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),* }) - }) + ::core::result::Result::Ok(Self { #(#field_names),* }) } }; builder_struct_generic_producers.push(quote! { Error_ }); diff --git a/ouroboros_macro/src/generate/with_all.rs b/ouroboros_macro/src/generate/with_all.rs index 03e3d59..e6a2665 100644 --- a/ouroboros_macro/src/generate/with_all.rs +++ b/ouroboros_macro/src/generate/with_all.rs @@ -16,20 +16,19 @@ pub fn make_with_all_function( let mut field_assignments = Vec::new(); let mut mut_fields = Vec::new(); let mut mut_field_assignments = Vec::new(); - let internal_struct = &info.internal_ident; // I don't think the reverse is necessary but it does make the expanded code more uniform. for field in info.fields.iter().rev() { let field_name = &field.name; let field_type = &field.typ; if field.field_type == FieldType::Tail { fields.push(quote! { #visibility #field_name: &'outer_borrow #field_type }); - field_assignments.push(quote! { #field_name: &this.#field_name }); + field_assignments.push(quote! { #field_name: &self.#field_name }); mut_fields.push(quote! { #visibility #field_name: &'outer_borrow mut #field_type }); - mut_field_assignments.push(quote! { #field_name: &mut this.#field_name }); + mut_field_assignments.push(quote! { #field_name: &mut self.#field_name }); } else if field.field_type == FieldType::Borrowed { let ass = quote! { #field_name: unsafe { ::ouroboros::macro_help::change_lifetime( - &*this.#field_name + &*self.#field_name ) } }; fields.push(quote! { #visibility #field_name: &'this #field_type }); @@ -109,7 +108,6 @@ pub fn make_with_all_function( } else { quote! { #[doc(hidden)] } }; - let generic_args = info.generic_arguments(); let fn_defs = quote! { #documentation #[inline(always)] @@ -117,7 +115,6 @@ pub fn make_with_all_function( &'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) }; user(BorrowedFields { #(#field_assignments),* }) @@ -128,7 +125,6 @@ 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) }; user(BorrowedMutFields { #(#mut_field_assignments),* }) diff --git a/ouroboros_macro/src/generate/with_each.rs b/ouroboros_macro/src/generate/with_each.rs index 15b0461..8985857 100644 --- a/ouroboros_macro/src/generate/with_each.rs +++ b/ouroboros_macro/src/generate/with_each.rs @@ -5,8 +5,6 @@ use syn::Error; pub fn make_with_functions(info: &StructInfo, options: Options) -> Result, Error> { let mut users = Vec::new(); - let internal_struct = &info.internal_ident; - let generic_args = info.generic_arguments(); for field in &info.fields { let visibility = &field.vis; let field_name = &field.name; @@ -36,8 +34,7 @@ pub fn make_with_functions(info: &StructInfo, options: Options) -> Result ::core::ops::FnOnce(&'outer_borrow #field_type) -> ReturnType, ) -> ReturnType { - let this: &#internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute(self) }; - user(&this. #field_name) + user(&self. #field_name) } }); if field.covariant == Some(true) { @@ -48,8 +45,7 @@ pub fn make_with_functions(info: &StructInfo, options: Options) -> Result( &'this self, ) -> &'this #field_type { - let this: &#internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute(self) }; - &this.#field_name + &self.#field_name } }); } else if field.covariant.is_none() { @@ -80,8 +76,7 @@ pub fn make_with_functions(info: &StructInfo, options: Options) -> Result ::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) + user(&mut self. #field_name) } }); } else if field.field_type == FieldType::Borrowed { @@ -107,8 +102,7 @@ pub fn make_with_functions(info: &StructInfo, options: Options) -> Result ::core::ops::FnOnce(&'outer_borrow #field_type) -> ReturnType, ) -> ReturnType { - let this: &#internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute(self) }; - user(&*this.#field_name) + user(&*self.#field_name) } }); if field.self_referencing { @@ -126,8 +120,7 @@ pub fn make_with_functions(info: &StructInfo, options: Options) -> Result( &'this self, ) -> &'this #field_type { - let this: &#internal_struct<#(#generic_args),*> = unsafe { ::core::mem::transmute(self) }; - &*this.#field_name + &*self.#field_name } }); } else if field.field_type == FieldType::BorrowedMut { diff --git a/ouroboros_macro/src/info_structures.rs b/ouroboros_macro/src/info_structures.rs index f2b0cc0..22e4cde 100644 --- a/ouroboros_macro/src/info_structures.rs +++ b/ouroboros_macro/src/info_structures.rs @@ -12,16 +12,6 @@ pub struct Options { pub do_pub_extras: bool, } -impl Options { - pub fn documentation_to_tokens(&self, documentation: &str) -> TokenStream { - if self.do_no_doc { - quote! { #[doc(hidden)] } - } else { - quote! { #[doc=#documentation] } - } - } -} - #[derive(Clone, Copy, PartialEq)] pub enum FieldType { /// Not borrowed by other parts of the struct. @@ -71,7 +61,6 @@ impl BuilderType { pub struct StructInfo { pub derives: Vec, pub ident: Ident, - pub internal_ident: Ident, pub generics: Generics, pub vis: Visibility, pub fields: Vec, diff --git a/ouroboros_macro/src/lib.rs b/ouroboros_macro/src/lib.rs index d0a6898..cd12419 100644 --- a/ouroboros_macro/src/lib.rs +++ b/ouroboros_macro/src/lib.rs @@ -9,7 +9,7 @@ mod utils; use crate::{ generate::{ constructor::create_builder_and_constructor, derives::create_derives, - into_heads::make_into_heads, struc::create_internal_struct_def, + into_heads::make_into_heads, struc::create_actual_struct_def, summon_checker::generate_checker_summoner, try_constructor::create_try_builder_and_constructor, type_asserts::make_type_asserts, with_all::make_with_all_function, with_each::make_with_functions, @@ -17,7 +17,6 @@ use crate::{ info_structures::Options, parse::parse_struct, }; -use generate::struc::create_actual_struct_def; use inflector::Inflector; use info_structures::BuilderType; use proc_macro::TokenStream; @@ -38,7 +37,6 @@ fn self_referencing_impl( let info = parse_struct(original_struct_def)?; let actual_struct_def = create_actual_struct_def(&info)?; - let internal_struct_def = create_internal_struct_def(&info)?; let borrowchk_summoner = generate_checker_summoner(&info)?; @@ -80,7 +78,6 @@ fn self_referencing_impl( use super::*; #[doc="The self-referencing struct."] #actual_struct_def - #internal_struct_def #borrowchk_summoner #builder_def #async_builder_def diff --git a/ouroboros_macro/src/parse.rs b/ouroboros_macro/src/parse.rs index 8d5fd1a..546aa7c 100644 --- a/ouroboros_macro/src/parse.rs +++ b/ouroboros_macro/src/parse.rs @@ -262,7 +262,6 @@ pub fn parse_struct(def: &ItemStruct) -> Result { return Ok(StructInfo { derives, ident: def.ident.clone(), - internal_ident: format_ident!("{}Internal", def.ident), generics: def.generics.clone(), fields, vis,