diff --git a/Cargo.lock b/Cargo.lock index 2cf973a..199f947 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -588,7 +588,7 @@ dependencies = [ [[package]] name = "savefile" -version = "0.17.10" +version = "0.17.11" dependencies = [ "arrayvec", "bit-set 0.5.3", @@ -614,7 +614,7 @@ dependencies = [ [[package]] name = "savefile-abi" -version = "0.17.10" +version = "0.17.11" dependencies = [ "byteorder", "libloading", @@ -655,7 +655,7 @@ dependencies = [ [[package]] name = "savefile-derive" -version = "0.17.10" +version = "0.17.11" dependencies = [ "proc-macro-error2", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index b56f5b9..069e50a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,6 @@ members = [ "savefile-abi-min-lib-impl" ] exclude = ["compile_tests"] - resolver = "2" [profile.dev.package] diff --git a/README.md b/README.md index 31709c6..e35d6de 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,11 @@ See the docs for more information, including schema-versioning: https://docs.rs/ # Changelog +## 0.17.11 + +Support Sync + Send-bounds for dyn Fn parameters, in savefile-abi. Also, reduce +risk of variable name conflicts between generated code and user code. + ## 0.17.10 Support for serializing the std::io::Error type. diff --git a/savefile-abi/Cargo.toml b/savefile-abi/Cargo.toml index 7587ebc..26745cf 100644 --- a/savefile-abi/Cargo.toml +++ b/savefile-abi/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "savefile-abi" -version = "0.17.10" +version = "0.17.11" edition = "2021" authors = ["Anders Musikka "] documentation = "https://docs.rs/savefile-abi/" @@ -17,8 +17,8 @@ keywords = ["dylib", "dlopen", "ffi"] license = "MIT/Apache-2.0" [dependencies] -savefile = { path="../savefile", version = "=0.17.10" } -savefile-derive = { path="../savefile-derive", version = "=0.17.10" } +savefile = { path="../savefile", version = "=0.17.11" } +savefile-derive = { path="../savefile-derive", version = "=0.17.11" } byteorder = "1.4" libloading = "0.8" diff --git a/savefile-derive/Cargo.toml b/savefile-derive/Cargo.toml index 4a99fd1..b1eb08b 100644 --- a/savefile-derive/Cargo.toml +++ b/savefile-derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "savefile-derive" -version = "0.17.10" +version = "0.17.11" authors = ["Anders Musikka "] repository = "https://github.com/avl/savefile" rust-version = "1.74" diff --git a/savefile-derive/src/savefile_abi.rs b/savefile-derive/src/savefile_abi.rs index a4618ab..f17088b 100644 --- a/savefile-derive/src/savefile_abi.rs +++ b/savefile-derive/src/savefile_abi.rs @@ -381,6 +381,7 @@ fn parse_type( ); } }) + .filter(|seg| seg.ident != "Send" && seg.ident != "Sync") .collect(); if type_bounds.len() == 0 { abort!(trait_obj.bounds.span(), "{}, unsupported trait object reference. Only &dyn Trait is supported. Encountered zero traits.", location); @@ -1062,15 +1063,15 @@ pub(super) fn generate_method_definitions( let compile_time_known_size = compile_time_known_size + 4; //Space for 'version' arg_buffer = quote! { - let mut rawdata = [0u8;#compile_time_known_size]; - let mut data = Cursor::new(&mut rawdata[..]); + let mut __savefile_internal_datarawdata = [0u8;#compile_time_known_size]; + let mut __savefile_internal_data = Cursor::new(&mut __savefile_internal_datarawdata[..]); }; - data_as_ptr = quote!(rawdata[..].as_ptr()); + data_as_ptr = quote!(__savefile_internal_datarawdata[..].as_ptr()); data_length = quote!( #compile_time_known_size ); } else { - arg_buffer = quote!( let mut data = FlexBuffer::new(); ); - data_as_ptr = quote!(data.as_ptr() as *const u8); - data_length = quote!(data.len()); + arg_buffer = quote!( let mut __savefile_internal_data = FlexBuffer::new(); ); + data_as_ptr = quote!(__savefile_internal_data.as_ptr() as *const u8); + data_length = quote!(__savefile_internal_data.len()); } let _ = caller_return_type; @@ -1093,7 +1094,7 @@ pub(super) fn generate_method_definitions( #(#caller_arg_serializers_temp)* let mut serializer = Serializer { - writer: &mut data, + writer: &mut __savefile_internal_data, file_version: self.template.effective_version, }; serializer.write_u32(self.template.effective_version).unwrap(); @@ -1162,21 +1163,21 @@ pub(super) fn generate_method_definitions( let compile_time_known_size = compile_time_known_size + 4; //Space for 'version' ret_buffer = quote! { - let mut rawdata = [0u8;#compile_time_known_size]; - let mut data = Cursor::new(&mut rawdata[..]); + let mut __savefile_internal_datarawdata = [0u8;#compile_time_known_size]; + let mut __savefile_internal_data = Cursor::new(&mut __savefile_internal_datarawdata[..]); }; - data_as_ptr = quote!(rawdata[..].as_ptr()); + data_as_ptr = quote!(__savefile_internal_datarawdata[..].as_ptr()); data_length = quote!( #compile_time_known_size ); } else { - ret_buffer = quote!( let mut data = FlexBuffer::new(); ); - data_as_ptr = quote!(data.as_ptr() as *const u8); - data_length = quote!(data.len()); + ret_buffer = quote!( let mut __savefile_internal_data = FlexBuffer::new(); ); + data_as_ptr = quote!(__savefile_internal_data.as_ptr() as *const u8); + data_length = quote!(__savefile_internal_data.len()); } handle_retval = quote! { #ret_buffer let mut serializer = Serializer { - writer: &mut data, + writer: &mut __savefile_internal_data, file_version: #version, }; diff --git a/savefile-test/Cargo.toml b/savefile-test/Cargo.toml index 64b41ac..d31062a 100644 --- a/savefile-test/Cargo.toml +++ b/savefile-test/Cargo.toml @@ -3,6 +3,8 @@ name = "savefile-test" version = "0.0.1" authors = ["Anders Musikka "] resolver = "2" +edition = "2021" + [features] default = ["external_benchmarks"] # Enable this to reduce risk of crashing on corrupt input. Provides sanity checks for sizes of objects. @@ -12,7 +14,7 @@ nightly=["savefile/nightly"] [dependencies] savefile = { path = "../savefile", features = ["size_sanity_checks", "encryption", "compression","bit-set","bit-vec","rustc-hash","serde_derive", "quickcheck", "nalgebra"]} -savefile-derive = { path = "../savefile-derive", version = "=0.17.10" } +savefile-derive = { path = "../savefile-derive", version = "=0.17.11" } savefile-abi = { path = "../savefile-abi" } bit-vec = "0.8" arrayvec="0.7" diff --git a/savefile-test/src/cycles.rs b/savefile-test/src/cycles.rs index 6785182..b7bb043 100644 --- a/savefile-test/src/cycles.rs +++ b/savefile-test/src/cycles.rs @@ -1,4 +1,4 @@ -use assert_roundtrip; +use crate::assert_roundtrip; use savefile::{get_schema, Removed, WithSchema, WithSchemaContext}; #[derive(Savefile, Debug, PartialEq)] @@ -65,6 +65,6 @@ struct Version2Base(Option>); expected = "Saved schema differs from in-memory schema for version 0. Error: At location [./Version1Base/0/?/Version1LevelA/0/?/Version1LevelB/0/Version1LevelC/0]: Application protocol uses recursion up 3 levels, but foreign format uses 2" )] fn cycles_vertest1() { - use assert_roundtrip_to_new_version; + use crate::assert_roundtrip_to_new_version; assert_roundtrip_to_new_version(Version1Base(None), 0, Version2Base(None), 1); } diff --git a/savefile-test/src/enum_variant_versioning.rs b/savefile-test/src/enum_variant_versioning.rs index bdb50fd..1e33491 100644 --- a/savefile-test/src/enum_variant_versioning.rs +++ b/savefile-test/src/enum_variant_versioning.rs @@ -1,6 +1,6 @@ -use assert_roundtrip_version; +use crate::assert_roundtrip_version; use savefile::{Packed, Removed}; -use {assert_roundtrip, assert_roundtrip_to_new_version}; +use crate::{assert_roundtrip, assert_roundtrip_to_new_version}; #[repr(u8)] #[derive(Savefile, Debug, PartialEq)] diff --git a/savefile-test/src/savefile_abi_test/advanced_datatypes_test.rs b/savefile-test/src/savefile_abi_test/advanced_datatypes_test.rs index 44b1e8d..980400c 100644 --- a/savefile-test/src/savefile_abi_test/advanced_datatypes_test.rs +++ b/savefile-test/src/savefile_abi_test/advanced_datatypes_test.rs @@ -1,13 +1,14 @@ use savefile_abi::AbiConnection; use savefile_abi::AbiExportable; use std::collections::HashMap; +use std::sync::{Arc, Mutex}; #[savefile_abi_exportable(version = 0)] pub trait SimpleInterface { fn do_call(&self, x: u32) -> u32; } #[savefile_abi_exportable(version = 0)] -pub trait AdvancedTestInterface { +pub trait AdvancedTestInterface : Send{ fn roundtrip_hashmap(&self, x: HashMap) -> HashMap; fn clone_hashmap(&self, x: &HashMap) -> HashMap; @@ -17,6 +18,9 @@ pub trait AdvancedTestInterface { fn return_boxed_closure(&self) -> Box u32>; fn return_boxed_closure2(&self) -> Box; fn many_callbacks(&mut self, x: &mut dyn FnMut(&dyn Fn(&dyn Fn() -> u32) -> u32) -> u32) -> u32; + + fn buf_callback(&mut self, cb: Box); + } struct SimpleImpl; @@ -60,8 +64,44 @@ impl AdvancedTestInterface for AdvancedTestInterfaceImpl { fn many_callbacks(&mut self, x: &mut dyn FnMut(&dyn Fn(&dyn Fn() -> u32) -> u32) -> u32) -> u32 { x(&|y| y()) } + + fn buf_callback(&mut self, cb: Box) { + cb(&[1,2,3], "hello".to_string()) + } +} + +struct TestUser(Box); + +pub trait DummyTrait2 : Send { + +} + +impl DummyTrait2 for TestUser { + +} +fn require_send(_t: T) { + +} +#[test] +fn abi_test_buf_send() { + let boxed: Box = Box::new(AdvancedTestInterfaceImpl {}); + require_send(boxed); } +#[test] +fn abi_test_buf_callback() { + let boxed: Box = Box::new(AdvancedTestInterfaceImpl {}); + let mut conn = AbiConnection::from_boxed_trait(boxed).unwrap(); + let buf = Arc::new(Mutex::new(None)); + let bufclone = Arc::clone(&buf); + conn.buf_callback(Box::new(move|argbuf, _s|{ + *bufclone.lock().unwrap() = Some(argbuf.to_vec()); + })); + let mut guard = buf.lock().unwrap(); + let vec = guard.take().unwrap(); + assert_eq!(vec, [1,2,3]); + +} #[test] fn abi_test_slice() { let boxed: Box = Box::new(AdvancedTestInterfaceImpl {}); diff --git a/savefile-test/src/savefile_abi_test/argument_backward_compatibility.rs b/savefile-test/src/savefile_abi_test/argument_backward_compatibility.rs index b104091..373f71d 100644 --- a/savefile-test/src/savefile_abi_test/argument_backward_compatibility.rs +++ b/savefile-test/src/savefile_abi_test/argument_backward_compatibility.rs @@ -2,9 +2,9 @@ use savefile::prelude::AbiRemoved; use savefile::{get_schema, SavefileError, WithSchemaContext}; use savefile_abi::RawAbiCallResult::AbiError; use savefile_abi::{verify_compatiblity, AbiConnection, AbiExportable}; -use savefile_abi_test::argument_backward_compatibility::v1::{ArgInterfaceV1, EnumArgument, Implementation1}; -use savefile_abi_test::argument_backward_compatibility::v2::{ArgInterfaceV2, Implementation2}; -use savefile_abi_test::basic_abi_tests::CowSmuggler; +use crate::savefile_abi_test::argument_backward_compatibility::v1::{ArgInterfaceV1, EnumArgument, Implementation1}; +use crate::savefile_abi_test::argument_backward_compatibility::v2::{ArgInterfaceV2, Implementation2}; +use crate::savefile_abi_test::basic_abi_tests::CowSmuggler; use savefile_derive::Savefile; mod v1 { diff --git a/savefile-test/src/savefile_abi_test/closure_tests.rs b/savefile-test/src/savefile_abi_test/closure_tests.rs index ab82458..e82ec5c 100644 --- a/savefile-test/src/savefile_abi_test/closure_tests.rs +++ b/savefile-test/src/savefile_abi_test/closure_tests.rs @@ -1,7 +1,7 @@ #![allow(non_camel_case_types)] use savefile_abi::{AbiConnection, AbiExportable}; -use savefile_abi_test::basic_abi_tests::{CallbackImpl, TestInterface, TestInterfaceImpl}; -use savefile_abi_test::closure_tests::new_version::ExampleImplementationNewer; +use crate::savefile_abi_test::basic_abi_tests::{CallbackImpl, TestInterface, TestInterfaceImpl}; +use crate::savefile_abi_test::closure_tests::new_version::ExampleImplementationNewer; #[derive(Savefile)] pub struct CustomArg { @@ -128,7 +128,7 @@ fn test_closure_with_custom_return_call_older() { //let old_def = ::get_definition(0); //println!("Old def: {:#?}", old_def); { - use savefile_abi_test::closure_tests::new_version::Example; + use crate::savefile_abi_test::closure_tests::new_version::Example; let result = conn.call_closure_return_custom_arg(&|arg| new_version::CustomArg { x: arg.x, y: "hej".to_string(), diff --git a/savefile-test/src/savefile_abi_test/enum_tests.rs b/savefile-test/src/savefile_abi_test/enum_tests.rs index a5392ea..931a95e 100644 --- a/savefile-test/src/savefile_abi_test/enum_tests.rs +++ b/savefile-test/src/savefile_abi_test/enum_tests.rs @@ -1,5 +1,5 @@ use savefile_abi::{AbiConnection, AbiExportable}; -use savefile_abi_test::basic_abi_tests::{TestInterface, TestInterfaceImpl}; +use crate::savefile_abi_test::basic_abi_tests::{TestInterface, TestInterfaceImpl}; #[derive(Savefile, Clone)] #[repr(C, u8)] diff --git a/savefile-test/src/test_arrayvec.rs b/savefile-test/src/test_arrayvec.rs index 2d25493..befab5e 100644 --- a/savefile-test/src/test_arrayvec.rs +++ b/savefile-test/src/test_arrayvec.rs @@ -1,5 +1,5 @@ use arrayvec::ArrayVec; -use assert_roundtrip; +use crate::assert_roundtrip; #[test] pub fn test_arrayvec0() { diff --git a/savefile-test/src/test_enum_many_variants.rs b/savefile-test/src/test_enum_many_variants.rs index d2b6444..39f8eac 100644 --- a/savefile-test/src/test_enum_many_variants.rs +++ b/savefile-test/src/test_enum_many_variants.rs @@ -1,4 +1,4 @@ -use assert_roundtrip; +use crate::assert_roundtrip; #[repr(u16)] #[derive(Savefile, Debug, PartialEq)] diff --git a/savefile-test/src/test_generic.rs b/savefile-test/src/test_generic.rs index 1d98afc..990f254 100644 --- a/savefile-test/src/test_generic.rs +++ b/savefile-test/src/test_generic.rs @@ -1,4 +1,4 @@ -use assert_roundtrip; +use crate::assert_roundtrip; use savefile::prelude::*; use std::fmt::Debug; use std::marker::{PhantomData, PhantomPinned}; diff --git a/savefile-test/src/test_introspect.rs b/savefile-test/src/test_introspect.rs index 5134b8a..be21550 100644 --- a/savefile-test/src/test_introspect.rs +++ b/savefile-test/src/test_introspect.rs @@ -1,5 +1,5 @@ use parking_lot::{Mutex, RwLock}; -use roundtrip; +use crate::roundtrip; use savefile::prelude::*; use savefile::{IntrospectedElementKey, IntrospectionError, Introspector, IntrospectorNavCommand}; use std::cell::RefCell; diff --git a/savefile-test/src/test_nested_non_repr_c.rs b/savefile-test/src/test_nested_non_repr_c.rs index c920d63..51f1d42 100644 --- a/savefile-test/src/test_nested_non_repr_c.rs +++ b/savefile-test/src/test_nested_non_repr_c.rs @@ -1,5 +1,5 @@ #![cfg(test)] -use roundtrip; +use crate::roundtrip; use savefile::prelude::*; #[derive(Clone, Copy, Debug, PartialEq, Savefile)] diff --git a/savefile-test/src/test_versioning.rs b/savefile-test/src/test_versioning.rs index 0ca29aa..5675efa 100644 --- a/savefile-test/src/test_versioning.rs +++ b/savefile-test/src/test_versioning.rs @@ -50,7 +50,7 @@ fn test_quickcheck_version3(xs: Version3) -> bool { #[test] fn simple_vertest1() { - use assert_roundtrip_to_new_version; + use crate::assert_roundtrip_to_new_version; let ver2: Version2 = assert_roundtrip_to_new_version( Version1 { a: "Hello".to_string(), @@ -97,7 +97,7 @@ enum EnumVer2 { #[test] fn test_versioning_of_enums() { - use assert_roundtrip_to_new_version; + use crate::assert_roundtrip_to_new_version; assert_roundtrip_to_new_version(EnumVer1::Variant1, 0, EnumVer2::Variant1, 1); assert_roundtrip_to_new_version(EnumVer1::Variant2, 0, EnumVer2::Variant2, 1); } @@ -120,7 +120,7 @@ enum EnumVerA2 { #[test] fn test_versioning_of_enums2() { - use assert_roundtrip_to_new_version; + use crate::assert_roundtrip_to_new_version; assert_roundtrip_to_new_version( EnumVerA1::Variant2 { x: 32, y: 33 }, 0, @@ -146,7 +146,7 @@ enum EnumVerB2 { #[test] fn test_versioning_of_enums3() { - use assert_roundtrip_to_new_version; + use crate::assert_roundtrip_to_new_version; assert_roundtrip_to_new_version( EnumVerB1::Variant2(32, 33), 0, @@ -183,7 +183,7 @@ struct ComplexData2 { #[test] fn test_versioning_of_enums4() { - use assert_roundtrip_to_new_version; + use crate::assert_roundtrip_to_new_version; assert_roundtrip_to_new_version( ComplexData1 { some_field: SubData1 { @@ -216,7 +216,7 @@ struct DefTraitTest { #[test] fn test_default_trait1() { - use assert_roundtrip_version; + use crate::assert_roundtrip_version; assert_roundtrip_version::( DefTraitTest { removed_enum: DefTraitEnum::VariantA, @@ -244,7 +244,7 @@ fn test_custom_default_fn() { b: String, } - use assert_roundtrip_to_new_version; + use crate::assert_roundtrip_to_new_version; assert_roundtrip_to_new_version( VersionB1 { a: "test".to_string() }, 0, @@ -267,7 +267,7 @@ struct AnewType { } use std::convert::From; -use {roundtrip, roundtrip_version}; +use crate::{roundtrip, roundtrip_version}; impl From for AnewType { fn from(_dummy: String) -> AnewType { @@ -284,7 +284,7 @@ struct StructWithAnotherType { #[test] fn test_change_type_of_field() { - use assert_roundtrip_to_new_version; + use crate::assert_roundtrip_to_new_version; assert_roundtrip_to_new_version( StructWithOneType { a_str: "test".to_string(), @@ -311,7 +311,7 @@ struct StructWithAnotherType2 { #[test] fn test_change_type_of_field2() { - use assert_roundtrip_to_new_version; + use crate::assert_roundtrip_to_new_version; assert_roundtrip_to_new_version( StructWithOneType { a_str: "422".to_string(), @@ -340,7 +340,7 @@ struct FastVersionA1 { #[test] fn simple_vertest_a() { - use assert_roundtrip_to_new_version; + use crate::assert_roundtrip_to_new_version; let _ver1: FastVersionA1 = assert_roundtrip_to_new_version( FastVersionA0 { a: 2, b: 3, c: 4 }, 0, @@ -368,7 +368,7 @@ struct FastVersionB1 { #[test] fn simple_vertest_b() { - use assert_roundtrip_to_new_version; + use crate::assert_roundtrip_to_new_version; let _ver1: FastVersionB1 = assert_roundtrip_to_new_version(FastVersionB0 { a: 2, b: 3 }, 0, FastVersionB1 { a: 2, b: 3, c: 0 }, 1); } diff --git a/savefile/Cargo.toml b/savefile/Cargo.toml index 95b299c..5e18e15 100644 --- a/savefile/Cargo.toml +++ b/savefile/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "savefile" -version = "0.17.10" +version = "0.17.11" authors = ["Anders Musikka "] documentation = "https://docs.rs/savefile/" homepage = "https://github.com/avl/savefile/" @@ -63,13 +63,13 @@ bit-set08 = {package="bit-set", version = "0.8", optional = true} rustc-hash = {version = "1.1", optional = true} memoffset = "0.9" byteorder = "1.4" -savefile-derive = {path="../savefile-derive", version = "=0.17.10", optional = true } +savefile-derive = {path="../savefile-derive", version = "=0.17.11", optional = true } serde_derive = {version= "1.0", optional = true} serde = {version= "1.0", optional = true} quickcheck = {version= "1.0", optional = true} [dev-dependencies] -savefile-derive = { path="../savefile-derive", version = "=0.17.10" } +savefile-derive = { path="../savefile-derive", version = "=0.17.11" } [build-dependencies] rustc_version="0.2" diff --git a/savefile/src/lib.rs b/savefile/src/lib.rs index 712baee..bdbaa1a 100644 --- a/savefile/src/lib.rs +++ b/savefile/src/lib.rs @@ -36,6 +36,9 @@ computer game is saved to disk using Savefile. ``` +# #[cfg(miri)] fn main() {} +# #[cfg(not(miri))] +# fn main() { extern crate savefile; use savefile::prelude::*; @@ -72,6 +75,7 @@ fn main() { assert_eq!(reloaded_player.name,"Steve".to_string()); } +# } ``` # Limitations of Savefile @@ -107,6 +111,9 @@ Mark the struct like so: ``` +# #[cfg(miri)] fn main() {} +# #[cfg(not(miri))] +# fn main() { extern crate savefile; use savefile::prelude::*; use std::path::Path; @@ -144,6 +151,7 @@ fn main() { player.skills.push("Whistling".to_string()); save_player("newsave.bin", &player); //The version saved here will have the vec of skills } +# } ``` @@ -426,6 +434,9 @@ Rules for using the #\[savefile_versions] attribute: ``` +# #[cfg(miri)] fn main() {} +# #[cfg(not(miri))] +# fn main() { extern crate savefile; use savefile::prelude::*; use std::path::Path; @@ -471,6 +482,7 @@ Rules for using the #\[savefile_versions] attribute: player.history.push(Position{x:2,y:2}); save_player("newersave.bin", &player); } +# } ``` Savefile can speed up serialization of arrays/vectors of certain types, when it can detect that the type consists entirely of packed plain binary data.