From dd7254f055b41f876a910820010ed1a5cd74ec1c Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 19 Sep 2019 06:36:57 +0200 Subject: [PATCH 1/3] Replace mem::uninitialized by MaybeUninit --- rustler/src/types/binary.rs | 18 +++++----- rustler/src/types/pid.rs | 10 +++--- rustler/src/wrapper.rs | 1 - rustler/src/wrapper/binary.rs | 34 ++++--------------- rustler/src/wrapper/env.rs | 14 ++++---- rustler/src/wrapper/list.rs | 16 ++++----- rustler/src/wrapper/map.rs | 53 +++++++++++++++--------------- rustler/src/wrapper/pid.rs | 8 ++--- rustler/src/wrapper/resource.rs | 12 +++---- rustler/src/wrapper/tuple.rs | 8 ++--- rustler_sys/src/rustler_sys_api.rs | 2 +- 11 files changed, 79 insertions(+), 97 deletions(-) diff --git a/rustler/src/types/binary.rs b/rustler/src/types/binary.rs index f29d3098..ea752f4f 100644 --- a/rustler/src/types/binary.rs +++ b/rustler/src/types/binary.rs @@ -1,6 +1,7 @@ use crate::wrapper::binary::{alloc, realloc, ErlNifBinary}; use crate::{Decoder, Encoder, Env, Error, NifResult, Term}; +use std::mem::MaybeUninit; use std::borrow::{Borrow, BorrowMut}; use std::io::Write; use std::ops::{Deref, DerefMut}; @@ -114,7 +115,7 @@ impl DerefMut for OwnedBinary { impl Drop for OwnedBinary { fn drop(&mut self) { if self.release { - unsafe { rustler_sys::enif_release_binary(self.inner.as_c_arg()) }; + unsafe { rustler_sys::enif_release_binary(&mut self.inner) }; } } } @@ -123,7 +124,6 @@ unsafe impl Send for OwnedBinary {} // Borrowed -#[derive(Copy, Clone)] pub struct Binary<'a> { inner: ErlNifBinary, term: Term<'a>, @@ -137,7 +137,7 @@ impl<'a> Binary<'a> { let term = unsafe { Term::new( env, - rustler_sys::enif_make_binary(env.as_c_arg(), bin.inner.as_c_arg()), + rustler_sys::enif_make_binary(env.as_c_arg(), &mut bin.inner), ) }; Binary { @@ -151,37 +151,37 @@ impl<'a> Binary<'a> { } pub fn from_term(term: Term<'a>) -> Result { - let mut binary = unsafe { ErlNifBinary::new_empty() }; + let mut binary = MaybeUninit::uninit(); if unsafe { rustler_sys::enif_inspect_binary( term.get_env().as_c_arg(), term.as_c_arg(), - binary.as_c_arg(), + binary.as_mut_ptr(), ) } == 0 { return Err(Error::BadArg); } Ok(Binary { - inner: binary, + inner: unsafe { binary.assume_init() }, term, }) } pub fn from_iolist(term: Term<'a>) -> Result { - let mut binary = unsafe { ErlNifBinary::new_empty() }; + let mut binary = MaybeUninit::uninit(); if unsafe { rustler_sys::enif_inspect_iolist_as_binary( term.get_env().as_c_arg(), term.as_c_arg(), - binary.as_c_arg(), + binary.as_mut_ptr(), ) } == 0 { return Err(Error::BadArg); } Ok(Binary { - inner: binary, + inner: unsafe { binary.assume_init() }, term, }) } diff --git a/rustler/src/types/pid.rs b/rustler/src/types/pid.rs index 90edde7a..00e1604a 100644 --- a/rustler/src/types/pid.rs +++ b/rustler/src/types/pid.rs @@ -1,6 +1,6 @@ use crate::wrapper::{pid, ErlNifPid}; use crate::{Decoder, Encoder, Env, Error, NifResult, Term}; -use std::mem; +use std::mem::MaybeUninit; #[derive(Clone)] pub struct Pid { @@ -36,10 +36,12 @@ impl<'a> Env<'a> { /// environment is to use `OwnedEnv`. The `Env` that Rustler passes to NIFs when they're /// called is always associated with the calling Erlang process.) pub fn pid(self) -> Pid { - let mut pid: ErlNifPid = unsafe { mem::uninitialized() }; - if unsafe { rustler_sys::enif_self(self.as_c_arg(), &mut pid) }.is_null() { + let mut pid = MaybeUninit::uninit(); + if unsafe { rustler_sys::enif_self(self.as_c_arg(), pid.as_mut_ptr()) }.is_null() { panic!("environment is process-independent"); } - Pid { c: pid } + Pid { + c: unsafe { pid.assume_init() }, + } } } diff --git a/rustler/src/wrapper.rs b/rustler/src/wrapper.rs index c9060424..b2ffe907 100644 --- a/rustler/src/wrapper.rs +++ b/rustler/src/wrapper.rs @@ -30,7 +30,6 @@ pub type size_t = usize; pub type NIF_ENV = *mut rustler_sys::ErlNifEnv; pub type NIF_TERM = size_t; -pub type NIF_BINARY = *mut rustler_sys::ErlNifBinary; pub type NIF_RESOURCE_TYPE = *const rustler_sys::ErlNifResourceType; pub fn get_nif_resource_type_init_size() -> usize { diff --git a/rustler/src/wrapper/binary.rs b/rustler/src/wrapper/binary.rs index a7eaf359..6e870e20 100644 --- a/rustler/src/wrapper/binary.rs +++ b/rustler/src/wrapper/binary.rs @@ -1,37 +1,17 @@ -use crate::wrapper::{c_void, size_t, NIF_BINARY}; -use std::mem::uninitialized; - -#[repr(C)] -#[derive(Copy, Clone)] -pub struct ErlNifBinary { - pub size: size_t, - pub data: *mut u8, - _internal: [*mut c_void; 3], -} - -impl ErlNifBinary { - pub unsafe fn new_empty() -> Self { - ErlNifBinary { - size: uninitialized(), - data: uninitialized(), - _internal: uninitialized(), - } - } - pub fn as_c_arg(&mut self) -> NIF_BINARY { - (self as *mut ErlNifBinary) as NIF_BINARY - } -} +use crate::wrapper::size_t; +pub(in crate) use rustler_sys::ErlNifBinary; +use std::mem::MaybeUninit; pub unsafe fn alloc(size: size_t) -> Option { - let mut binary = ErlNifBinary::new_empty(); - let success = rustler_sys::enif_alloc_binary(size, binary.as_c_arg()); + let mut binary = MaybeUninit::uninit(); + let success = rustler_sys::enif_alloc_binary(size, binary.as_mut_ptr()); if success == 0 { return None; } - Some(binary) + Some(binary.assume_init()) } pub unsafe fn realloc(binary: &mut ErlNifBinary, size: size_t) -> bool { - let success = rustler_sys::enif_realloc_binary(binary.as_c_arg(), size); + let success = rustler_sys::enif_realloc_binary(binary, size); success != 0 } diff --git a/rustler/src/wrapper/env.rs b/rustler/src/wrapper/env.rs index cbdf2650..77f3b990 100644 --- a/rustler/src/wrapper/env.rs +++ b/rustler/src/wrapper/env.rs @@ -1,28 +1,28 @@ use crate::wrapper::binary::ErlNifBinary; use crate::wrapper::{ERL_NIF_BIN2TERM_SAFE, NIF_ENV, NIF_TERM}; -use std::mem; +use std::mem::MaybeUninit; pub unsafe fn binary_to_term(env: NIF_ENV, data: &[u8], safe: bool) -> Option<(NIF_TERM, usize)> { let opts = if safe { ERL_NIF_BIN2TERM_SAFE } else { 0 }; - let mut result: NIF_TERM = mem::uninitialized(); + let mut result = MaybeUninit::uninit(); let read_count = - rustler_sys::enif_binary_to_term(env, data.as_ptr(), data.len(), &mut result, opts); + rustler_sys::enif_binary_to_term(env, data.as_ptr(), data.len(), result.as_mut_ptr(), opts); if read_count == 0 { return None; } - Some((result, read_count)) + Some((result.assume_init(), read_count)) } pub unsafe fn term_to_binary(env: NIF_ENV, term: NIF_TERM) -> Option { - let mut binary = ErlNifBinary::new_empty(); - let success = rustler_sys::enif_term_to_binary(env, term, binary.as_c_arg()); + let mut binary = MaybeUninit::uninit(); + let success = rustler_sys::enif_term_to_binary(env, term, binary.as_mut_ptr()); if success == 0 { return None; } - Some(binary) + Some(binary.assume_init()) } diff --git a/rustler/src/wrapper/list.rs b/rustler/src/wrapper/list.rs index e18924e2..af62a47e 100644 --- a/rustler/src/wrapper/list.rs +++ b/rustler/src/wrapper/list.rs @@ -1,15 +1,15 @@ use crate::wrapper::{NIF_ENV, NIF_TERM}; -use std::mem; +use std::mem::MaybeUninit; pub unsafe fn get_list_cell(env: NIF_ENV, list: NIF_TERM) -> Option<(NIF_TERM, NIF_TERM)> { - let mut head: NIF_TERM = mem::uninitialized(); - let mut tail: NIF_TERM = mem::uninitialized(); - let success = rustler_sys::enif_get_list_cell(env, list, &mut head, &mut tail); + let mut head = MaybeUninit::uninit(); + let mut tail = MaybeUninit::uninit(); + let success = rustler_sys::enif_get_list_cell(env, list, head.as_mut_ptr(), tail.as_mut_ptr()); if success != 1 { return None; } - Some((head, tail)) + Some((head.assume_init(), tail.assume_init())) } pub unsafe fn get_list_length(env: NIF_ENV, list: NIF_TERM) -> Option { @@ -31,11 +31,11 @@ pub unsafe fn make_list_cell(env: NIF_ENV, head: NIF_TERM, tail: NIF_TERM) -> NI } pub unsafe fn make_reverse_list(env: NIF_ENV, list: NIF_TERM) -> Option { - let mut list_out: NIF_TERM = mem::uninitialized(); - let success = rustler_sys::enif_make_reverse_list(env, list, &mut list_out); + let mut list_out = MaybeUninit::uninit(); + let success = rustler_sys::enif_make_reverse_list(env, list, list_out.as_mut_ptr()); if success != 1 { return None; } - Some(list_out) + Some(list_out.assume_init()) } diff --git a/rustler/src/wrapper/map.rs b/rustler/src/wrapper/map.rs index 275d53a7..5fc662b6 100644 --- a/rustler/src/wrapper/map.rs +++ b/rustler/src/wrapper/map.rs @@ -1,25 +1,25 @@ pub use crate::wrapper::ErlNifMapIterator; use crate::wrapper::{ErlNifMapIteratorEntry, NIF_ENV, NIF_TERM}; -use std::mem; +use std::mem::MaybeUninit; pub unsafe fn get_map_value(env: NIF_ENV, map: NIF_TERM, key: NIF_TERM) -> Option { - let mut result: NIF_TERM = mem::uninitialized(); - let success = rustler_sys::enif_get_map_value(env, map, key, &mut result); + let mut result = MaybeUninit::uninit(); + let success = rustler_sys::enif_get_map_value(env, map, key, result.as_mut_ptr()); if success != 1 { return None; } - Some(result) + Some(result.assume_init()) } pub unsafe fn get_map_size(env: NIF_ENV, map: NIF_TERM) -> Option { - let mut size: rustler_sys::size_t = mem::uninitialized(); - let success = rustler_sys::enif_get_map_size(env, map, &mut size); + let mut size = MaybeUninit::uninit(); + let success = rustler_sys::enif_get_map_size(env, map, size.as_mut_ptr()); if success != 1 { return None; } - Some(size) + Some(size.assume_init()) } pub unsafe fn map_new(env: NIF_ENV) -> NIF_TERM { @@ -32,23 +32,23 @@ pub unsafe fn map_put( key: NIF_TERM, value: NIF_TERM, ) -> Option { - let mut result: NIF_TERM = mem::uninitialized(); - let success = rustler_sys::enif_make_map_put(env, map, key, value, &mut result); + let mut result = MaybeUninit::uninit(); + let success = rustler_sys::enif_make_map_put(env, map, key, value, result.as_mut_ptr()); if success != 1 { return None; } - Some(result) + Some(result.assume_init()) } pub unsafe fn map_remove(env: NIF_ENV, map: NIF_TERM, key: NIF_TERM) -> Option { - let mut result: NIF_TERM = mem::uninitialized(); - let success = rustler_sys::enif_make_map_remove(env, map, key, &mut result); + let mut result = MaybeUninit::uninit(); + let success = rustler_sys::enif_make_map_remove(env, map, key, result.as_mut_ptr()); if success != 1 { return None; } - Some(result) + Some(result.assume_init()) } pub unsafe fn map_update( @@ -57,27 +57,27 @@ pub unsafe fn map_update( key: NIF_TERM, new_value: NIF_TERM, ) -> Option { - let mut result: NIF_TERM = mem::uninitialized(); - let success = rustler_sys::enif_make_map_update(env, map, key, new_value, &mut result); + let mut result = MaybeUninit::uninit(); + let success = rustler_sys::enif_make_map_update(env, map, key, new_value, result.as_mut_ptr()); if success != 1 { return None; } - Some(result) + Some(result.assume_init()) } pub unsafe fn map_iterator_create(env: NIF_ENV, map: NIF_TERM) -> Option { - let mut iter = mem::uninitialized(); + let mut iter = MaybeUninit::uninit(); let success = rustler_sys::enif_map_iterator_create( env, map, - &mut iter, + iter.as_mut_ptr(), ErlNifMapIteratorEntry::ERL_NIF_MAP_ITERATOR_HEAD, ); if success == 0 { None } else { - Some(iter) + Some(iter.assume_init()) } } @@ -89,12 +89,13 @@ pub unsafe fn map_iterator_get_pair( env: NIF_ENV, iter: &mut ErlNifMapIterator, ) -> Option<(NIF_TERM, NIF_TERM)> { - let mut key: NIF_TERM = mem::uninitialized(); - let mut value: NIF_TERM = mem::uninitialized(); - if rustler_sys::enif_map_iterator_get_pair(env, iter, &mut key, &mut value) == 0 { + let mut key = MaybeUninit::uninit(); + let mut value = MaybeUninit::uninit(); + if rustler_sys::enif_map_iterator_get_pair(env, iter, key.as_mut_ptr(), value.as_mut_ptr()) == 0 + { None } else { - Some((key, value)) + Some((key.assume_init(), value.assume_init())) } } @@ -108,17 +109,17 @@ pub unsafe fn make_map_from_arrays( keys: &[NIF_TERM], values: &[NIF_TERM], ) -> Option { - let mut map = mem::uninitialized(); + let mut map = MaybeUninit::uninit(); if rustler_sys::enif_make_map_from_arrays( env, keys.as_ptr(), values.as_ptr(), keys.len() as usize, - &mut map, + map.as_mut_ptr(), ) == 0 { return None; } - Some(map) + Some(map.assume_init()) } diff --git a/rustler/src/wrapper/pid.rs b/rustler/src/wrapper/pid.rs index e9b9585d..1a28992b 100644 --- a/rustler/src/wrapper/pid.rs +++ b/rustler/src/wrapper/pid.rs @@ -1,12 +1,12 @@ use crate::wrapper::{ErlNifPid, NIF_ENV, NIF_TERM}; -use std::mem; +use std::mem::MaybeUninit; pub unsafe fn get_local_pid(env: NIF_ENV, term: NIF_TERM) -> Option { - let mut pid: ErlNifPid = mem::uninitialized(); - if rustler_sys::enif_get_local_pid(env, term, &mut pid) == 0 { + let mut pid = MaybeUninit::uninit(); + if rustler_sys::enif_get_local_pid(env, term, pid.as_mut_ptr()) == 0 { return None; } - Some(pid) + Some(pid.assume_init()) } // pub unsafe fn is_process_alive(env: NIF_ENV, pid: &ErlNifPid) -> bool { diff --git a/rustler/src/wrapper/resource.rs b/rustler/src/wrapper/resource.rs index 37e6117d..903ca162 100644 --- a/rustler/src/wrapper/resource.rs +++ b/rustler/src/wrapper/resource.rs @@ -9,7 +9,7 @@ pub use rustler_sys::{ pub use rustler_sys::enif_release_resource as release_resource; -use std::mem; +use std::mem::MaybeUninit; use std::ptr; pub unsafe fn open_resource_type( @@ -25,8 +25,8 @@ pub unsafe fn open_resource_type( let module_p: *const u8 = ptr::null(); let name_p = name.as_ptr(); let res = { - let mut tried: NifResourceFlags = mem::uninitialized(); - rustler_sys::enif_open_resource_type(env, module_p, name_p, dtor, flags, &mut tried) + let mut tried = MaybeUninit::uninit(); + rustler_sys::enif_open_resource_type(env, module_p, name_p, dtor, flags, tried.as_mut_ptr()) }; if res.is_null() { @@ -42,12 +42,12 @@ pub unsafe fn get_resource( term: NIF_TERM, typ: NIF_RESOURCE_TYPE, ) -> Option { - let mut ret_obj: NIF_RESOURCE_HANDLE = mem::uninitialized(); - let res = rustler_sys::enif_get_resource(env, term, typ, &mut ret_obj); + let mut ret_obj = MaybeUninit::uninit(); + let res = rustler_sys::enif_get_resource(env, term, typ, ret_obj.as_mut_ptr()); if res == 0 { None } else { - Some(ret_obj) + Some(ret_obj.assume_init()) } } diff --git a/rustler/src/wrapper/tuple.rs b/rustler/src/wrapper/tuple.rs index 65928355..233ae74f 100644 --- a/rustler/src/wrapper/tuple.rs +++ b/rustler/src/wrapper/tuple.rs @@ -1,14 +1,14 @@ use crate::wrapper::{c_int, NIF_ENV, NIF_ERROR, NIF_TERM}; -use std::mem; +use std::mem::MaybeUninit; pub unsafe fn get_tuple<'a>(env: NIF_ENV, term: NIF_TERM) -> Result<&'a [NIF_TERM], NIF_ERROR> { let mut arity: c_int = 0; - let mut array_ptr: *const NIF_TERM = mem::uninitialized(); - let success = rustler_sys::enif_get_tuple(env, term, &mut arity, &mut array_ptr); + let mut array_ptr = MaybeUninit::uninit(); + let success = rustler_sys::enif_get_tuple(env, term, &mut arity, array_ptr.as_mut_ptr()); if success != 1 { return Err(NIF_ERROR::BAD_ARG); } - let term_array = ::std::slice::from_raw_parts(array_ptr, arity as usize); + let term_array = ::std::slice::from_raw_parts(array_ptr.assume_init(), arity as usize); Ok(term_array) } diff --git a/rustler_sys/src/rustler_sys_api.rs b/rustler_sys/src/rustler_sys_api.rs index 0b24187d..0d50f0eb 100644 --- a/rustler_sys/src/rustler_sys_api.rs +++ b/rustler_sys/src/rustler_sys_api.rs @@ -91,7 +91,7 @@ pub const ERL_NIF_DIRTY_NIF_OPTION: c_uint = 1; /// See [ErlNifBinary](http://www.erlang.org/doc/man/erl_nif.html#ErlNifBinary) in the Erlang docs. #[allow(missing_copy_implementations)] -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] #[repr(C)] pub struct ErlNifBinary { pub size: size_t, From b86130bf78d97d2e34f98ac51d10ed396bbcb393 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 19 Sep 2019 06:41:20 +0200 Subject: [PATCH 2/3] Run cargo fmt --- rustler/src/thread.rs | 4 ++-- rustler/src/types/binary.rs | 2 +- rustler_sys/src/initmacro.rs | 2 -- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/rustler/src/thread.rs b/rustler/src/thread.rs index 1a3cfbe1..763b0bb0 100644 --- a/rustler/src/thread.rs +++ b/rustler/src/thread.rs @@ -1,8 +1,8 @@ use crate::env::OwnedEnv; -use std::panic; -use std::thread; use crate::types::atom::Atom; use crate::{Encoder, Env, Term}; +use std::panic; +use std::thread; /// A `JobSpawner` is a value that can run Rust code on non-Erlang system threads. /// Abstracts away details of thread management for `spawn()`. diff --git a/rustler/src/types/binary.rs b/rustler/src/types/binary.rs index ea752f4f..8ceda14a 100644 --- a/rustler/src/types/binary.rs +++ b/rustler/src/types/binary.rs @@ -1,9 +1,9 @@ use crate::wrapper::binary::{alloc, realloc, ErlNifBinary}; use crate::{Decoder, Encoder, Env, Error, NifResult, Term}; -use std::mem::MaybeUninit; use std::borrow::{Borrow, BorrowMut}; use std::io::Write; +use std::mem::MaybeUninit; use std::ops::{Deref, DerefMut}; // Owned diff --git a/rustler_sys/src/initmacro.rs b/rustler_sys/src/initmacro.rs index e8a7e847..f85a0d72 100644 --- a/rustler_sys/src/initmacro.rs +++ b/rustler_sys/src/initmacro.rs @@ -350,7 +350,6 @@ mod initmacro_namespace_tests { }); assert_eq!(0, funcs[0].flags); } - } #[cfg(test)] @@ -629,5 +628,4 @@ mod initmacro_tests { }); assert_eq!(0, funcs[0].flags); } - } From 152b554471bd41cb3f63a7775326c0f84606bd72 Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Thu, 19 Sep 2019 07:10:39 +0200 Subject: [PATCH 3/3] Fix clippy warnings --- rustler/src/resource.rs | 10 ++-------- .../native/rustler_test/src/test_primitives.rs | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/rustler/src/resource.rs b/rustler/src/resource.rs index 556952f7..6bea5617 100644 --- a/rustler/src/resource.rs +++ b/rustler/src/resource.rs @@ -85,14 +85,8 @@ pub fn open_struct_resource_type<'a, T: ResourceTypeProvider>( flags, ) }; - if let Some(res) = res { - Some(ResourceType { - res, - struct_type: PhantomData, - }) - } else { - None - } + + res.map(|r| ResourceType { res: r, struct_type: PhantomData}) } fn get_alloc_size_struct() -> usize { diff --git a/rustler_tests/native/rustler_test/src/test_primitives.rs b/rustler_tests/native/rustler_test/src/test_primitives.rs index 5821d137..dc7d3933 100644 --- a/rustler_tests/native/rustler_test/src/test_primitives.rs +++ b/rustler_tests/native/rustler_test/src/test_primitives.rs @@ -20,7 +20,7 @@ pub fn echo_u8<'a>(env: Env<'a>, args: &[Term<'a>]) -> NifResult> { pub fn option_inc<'a>(env: Env<'a>, args: &[Term<'a>]) -> NifResult> { let opt: Option = args[0].decode()?; - let incremented = opt.and_then(|num| Some(num + 1.0)); + let incremented = opt.map(|num| num + 1.0); Ok(incremented.encode(env)) }