From df078725965297c2920403d5ffc1c230273058d5 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Fri, 30 Aug 2019 07:51:58 +0200 Subject: [PATCH] fix: Add tests and fix the regression with clone_userdata cc #779 cc @Etherian --- codegen/src/userdata.rs | 6 +++--- examples/marshalling.rs | 5 ++++- parser/src/grammar.lalrpop | 4 ++-- tests/api.rs | 25 +++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/codegen/src/userdata.rs b/codegen/src/userdata.rs index 5a2ef9f2d3..e370998ba0 100644 --- a/codegen/src/userdata.rs +++ b/codegen/src/userdata.rs @@ -55,10 +55,10 @@ fn gen_impl(container: &Container, ident: Ident, generics: Generics) -> TokenStr let deep_clone = if container.clone { quote! { - fn deep_clone( + fn deep_clone<'gc>( &self, - deep_cloner: &mut _gluon_api::Cloner - ) -> _gluon_Result<_gluon_gc::GcPtr>> { + deep_cloner: &'gc mut _gluon_api::Cloner + ) -> _gluon_Result<_gluon_gc::GcRef<'gc, Box>> { let data: Box = Box::new(self.clone()); deep_cloner.gc().alloc(_gluon_gc::Move(data)) } diff --git a/examples/marshalling.rs b/examples/marshalling.rs index 2222fa5d92..9319150a40 100644 --- a/examples/marshalling.rs +++ b/examples/marshalling.rs @@ -334,7 +334,9 @@ fn marshal_wrapper() -> Result<()> { Ok(()) } -#[derive(Userdata, Trace, Debug, Clone, VmType)] +#[derive(Userdata, Trace, Clone, Debug, VmType)] +#[gluon_userdata(clone)] +// Lets gluon know that the value can be cloned which can be needed when transferring the value between threads #[gluon(vm_type = "WindowHandle")] struct WindowHandle { id: Arc, @@ -348,6 +350,7 @@ fn load_mod(vm: &gluon::Thread) -> vm::Result { create_hwnd => primitive!(2, create_hwnd), id => primitive!(1, id), metadata => primitive!(1, metadata), + default_hwnd => create_hwnd(0, "default".into()), }; ExternModule::new(vm, module) diff --git a/parser/src/grammar.lalrpop b/parser/src/grammar.lalrpop index df277f0111..a60fc1b2c1 100644 --- a/parser/src/grammar.lalrpop +++ b/parser/src/grammar.lalrpop @@ -806,7 +806,7 @@ Expr: Expr = { }, "rec" => { - let mut bindings = bindings.into_iter().map(|x| *x).collect::>();; + let mut bindings = bindings.into_iter().map(|x| *x).collect::>(); if let Some(metadata) = metadata { bindings[0].metadata = metadata; } @@ -814,7 +814,7 @@ Expr: Expr = { }, "rec" => { - let mut bindings = bindings.into_iter().map(|x| *x).collect::>();; + let mut bindings = bindings.into_iter().map(|x| *x).collect::>(); if let Some(metadata) = metadata { bindings[0].metadata = metadata; } diff --git a/tests/api.rs b/tests/api.rs index d90c254425..2a999373ce 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -705,3 +705,28 @@ fn child_vm_do_not_cause_undroppable_cycle_reverse_drop_order() { "The virtual machine and its values were not dropped" ); } + +#[test] +fn clone_userdata() { + let _ = ::env_logger::try_init(); + + let expr = r#" + import! test + "#; + + #[derive(Debug, Userdata, Trace, VmType, Clone, PartialEq)] + #[gluon(vm_type = "Test")] + #[gluon_userdata(clone)] + struct Test(VmInt); + + let vm = make_vm(); + vm.register_type::("Test", &[]) + .unwrap_or_else(|_| panic!("Could not add type")); + add_extern_module(&vm, "test", |thread| ExternModule::new(thread, Test(123))); + + let (result, _) = Compiler::new() + .run_expr::>(&vm, "", expr) + .unwrap_or_else(|err| panic!("{}", err)); + + assert_eq!(*result, Test(123)); +}