From 8bb9d7546f66319c359aed77aefb516e02e40e54 Mon Sep 17 00:00:00 2001 From: Gabriel de Perthuis Date: Sun, 20 Dec 2020 12:25:59 +0100 Subject: [PATCH 1/2] Make sure OCaml values are always copyable --- src/value.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/value.rs b/src/value.rs index 439d0ef..32189d3 100644 --- a/src/value.rs +++ b/src/value.rs @@ -10,12 +10,27 @@ use ocaml_sys::{caml_string_length, int_val, val_int}; /// Should not be instantiated directly, and will usually be the result /// of [`ocaml_alloc!`] and [`ocaml_call!`] expressions, or the input arguments /// of functions defined inside [`ocaml_export!`] blocks. -#[derive(Copy, Clone)] pub struct OCaml<'a, T: 'a> { _marker: PhantomData<&'a T>, raw: RawOCaml, } +// Trivial, manual implementation because the derive is overly conservative +// and places bounds on type parameter T +// https://github.com/rust-lang/rust/issues/26925 +// https://github.com/rust-lang/rust/issues/52079 +impl<'a, T: 'a> Clone for OCaml<'a, T> { + fn clone(&self) -> Self { + Self { + _marker: PhantomData, + raw: self.raw, + } + } +} + +// As above, avoid unnecessary bounds +impl<'a, T: 'a> Copy for OCaml<'a, T> {} + pub fn make_ocaml<'a, T>(x: RawOCaml) -> OCaml<'a, T> { OCaml { _marker: PhantomData, From e6200b5155b8a6d5a56cc8b07df1497ef385d7c4 Mon Sep 17 00:00:00 2001 From: Gabriel de Perthuis Date: Sun, 20 Dec 2020 19:05:47 +0100 Subject: [PATCH 2/2] Implement ToOCaml for OCaml values This allows doing conversion in steps (eg, using a custom conversion to build list elements, then converting to OCamlList) and gives more control. --- src/conv/to_ocaml.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/conv/to_ocaml.rs b/src/conv/to_ocaml.rs index 877a4bf..f49500b 100644 --- a/src/conv/to_ocaml.rs +++ b/src/conv/to_ocaml.rs @@ -250,3 +250,9 @@ where }) } } + +unsafe impl<'a, A> ToOCaml for OCaml<'a, A> { + fn to_ocaml(&self, _token: OCamlAllocToken) -> OCamlAllocResult { + OCamlAllocResult::of_ocaml(*self) + } +}