From 53c99f940e3c66e1ec0e7d54456925db1b4c5f07 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Mon, 6 Apr 2020 19:38:33 -0700 Subject: [PATCH 1/2] Fix up conventions around unsafe in internal functions --- src/backup.rs | 8 ++++---- src/error.rs | 4 ++-- src/hooks.rs | 16 ++++++++-------- src/inner_connection.rs | 32 +++++++++++++++++--------------- src/raw_statement.rs | 6 +++--- src/statement.rs | 4 ++-- src/unlock_notify.rs | 22 ++++++++++------------ 7 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/backup.rs b/src/backup.rs index 1018ab6..e095146 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -77,8 +77,8 @@ impl Connection { match r { Done => Ok(()), - Busy => Err(error_from_handle(ptr::null_mut(), ffi::SQLITE_BUSY)), - Locked => Err(error_from_handle(ptr::null_mut(), ffi::SQLITE_LOCKED)), + Busy => Err(unsafe { error_from_handle(ptr::null_mut(), ffi::SQLITE_BUSY) }), + Locked => Err(unsafe { error_from_handle(ptr::null_mut(), ffi::SQLITE_LOCKED) }), More => unreachable!(), } } @@ -123,8 +123,8 @@ impl Connection { match r { Done => Ok(()), - Busy => Err(error_from_handle(ptr::null_mut(), ffi::SQLITE_BUSY)), - Locked => Err(error_from_handle(ptr::null_mut(), ffi::SQLITE_LOCKED)), + Busy => Err(unsafe { error_from_handle(ptr::null_mut(), ffi::SQLITE_BUSY) }), + Locked => Err(unsafe { error_from_handle(ptr::null_mut(), ffi::SQLITE_LOCKED) }), More => unreachable!(), } } diff --git a/src/error.rs b/src/error.rs index 50ff32d..34d2ddc 100644 --- a/src/error.rs +++ b/src/error.rs @@ -357,11 +357,11 @@ pub fn error_from_sqlite_code(code: c_int, message: Option) -> Error { Error::SqliteFailure(ffi::Error::new(code), message) } -pub fn error_from_handle(db: *mut ffi::sqlite3, code: c_int) -> Error { +pub unsafe fn error_from_handle(db: *mut ffi::sqlite3, code: c_int) -> Error { let message = if db.is_null() { None } else { - Some(unsafe { errmsg_to_string(ffi::sqlite3_errmsg(db)) }) + Some(errmsg_to_string(ffi::sqlite3_errmsg(db))) }; error_from_sqlite_code(code, message) } diff --git a/src/hooks.rs b/src/hooks.rs index 4b023f5..0691f31 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -102,7 +102,7 @@ impl InnerConnection { // `sqlite3_commit_hook`. so we keep the `xDestroy` function in // `InnerConnection.free_boxed_hook`. let free_commit_hook = if hook.is_some() { - Some(free_boxed_hook:: as fn(*mut c_void)) + Some(free_boxed_hook:: as unsafe fn(*mut c_void)) } else { None }; @@ -122,7 +122,7 @@ impl InnerConnection { }; if !previous_hook.is_null() { if let Some(free_boxed_hook) = self.free_commit_hook { - free_boxed_hook(previous_hook); + unsafe { free_boxed_hook(previous_hook) }; } } self.free_commit_hook = free_commit_hook; @@ -143,7 +143,7 @@ impl InnerConnection { } let free_rollback_hook = if hook.is_some() { - Some(free_boxed_hook:: as fn(*mut c_void)) + Some(free_boxed_hook:: as unsafe fn(*mut c_void)) } else { None }; @@ -163,7 +163,7 @@ impl InnerConnection { }; if !previous_hook.is_null() { if let Some(free_boxed_hook) = self.free_rollback_hook { - free_boxed_hook(previous_hook); + unsafe { free_boxed_hook(previous_hook) }; } } self.free_rollback_hook = free_rollback_hook; @@ -202,7 +202,7 @@ impl InnerConnection { } let free_update_hook = if hook.is_some() { - Some(free_boxed_hook:: as fn(*mut c_void)) + Some(free_boxed_hook:: as unsafe fn(*mut c_void)) } else { None }; @@ -222,15 +222,15 @@ impl InnerConnection { }; if !previous_hook.is_null() { if let Some(free_boxed_hook) = self.free_update_hook { - free_boxed_hook(previous_hook); + unsafe { free_boxed_hook(previous_hook) }; } } self.free_update_hook = free_update_hook; } } -fn free_boxed_hook(p: *mut c_void) { - drop(unsafe { Box::from_raw(p as *mut F) }); +unsafe fn free_boxed_hook(p: *mut c_void) { + drop(Box::from_raw(p as *mut F)); } #[cfg(test)] diff --git a/src/inner_connection.rs b/src/inner_connection.rs index c6694ef..88e6957 100644 --- a/src/inner_connection.rs +++ b/src/inner_connection.rs @@ -27,17 +27,17 @@ pub struct InnerConnection { // interrupt would only acquire the lock after the query's completion. interrupt_lock: Arc>, #[cfg(feature = "hooks")] - pub free_commit_hook: Option, + pub free_commit_hook: Option, #[cfg(feature = "hooks")] - pub free_rollback_hook: Option, + pub free_rollback_hook: Option, #[cfg(feature = "hooks")] - pub free_update_hook: Option, + pub free_update_hook: Option, owned: bool, } impl InnerConnection { #[allow(clippy::mutex_atomic)] - pub fn new(db: *mut ffi::sqlite3, owned: bool) -> InnerConnection { + pub unsafe fn new(db: *mut ffi::sqlite3, owned: bool) -> InnerConnection { InnerConnection { db, interrupt_lock: Arc::new(Mutex::new(db)), @@ -127,10 +127,10 @@ impl InnerConnection { } pub fn decode_result(&mut self, code: c_int) -> Result<()> { - InnerConnection::decode_result_raw(self.db(), code) + unsafe { InnerConnection::decode_result_raw(self.db(), code) } } - fn decode_result_raw(db: *mut ffi::sqlite3, code: c_int) -> Result<()> { + unsafe fn decode_result_raw(db: *mut ffi::sqlite3, code: c_int) -> Result<()> { if code == ffi::SQLITE_OK { Ok(()) } else { @@ -229,9 +229,9 @@ impl InnerConnection { } pub fn prepare<'a>(&mut self, conn: &'a Connection, sql: &str) -> Result> { - let mut c_stmt = MaybeUninit::uninit(); + let mut c_stmt = ptr::null_mut(); let (c_sql, len, _) = str_for_sqlite(sql.as_bytes())?; - let mut c_tail = MaybeUninit::uninit(); + let mut c_tail = ptr::null(); let r = unsafe { if cfg!(feature = "unlock_notify") { let mut rc; @@ -240,8 +240,8 @@ impl InnerConnection { self.db(), c_sql, len, - c_stmt.as_mut_ptr(), - c_tail.as_mut_ptr(), + &mut c_stmt as *mut *mut ffi::sqlite3_stmt, + &mut c_tail as *mut *const c_char, ); if !unlock_notify::is_locked(self.db, rc) { break; @@ -257,8 +257,8 @@ impl InnerConnection { self.db(), c_sql, len, - c_stmt.as_mut_ptr(), - c_tail.as_mut_ptr(), + &mut c_stmt as *mut *mut ffi::sqlite3_stmt, + &mut c_tail as *mut *const c_char, ) } }; @@ -266,11 +266,13 @@ impl InnerConnection { self.decode_result(r)?; // If the input text contains no SQL (if the input is an empty string or a // comment) then *ppStmt is set to NULL. - let c_stmt: *mut ffi::sqlite3_stmt = unsafe { c_stmt.assume_init() }; - let c_tail: *const c_char = unsafe { c_tail.assume_init() }; + let c_stmt: *mut ffi::sqlite3_stmt = c_stmt; + let c_tail: *const c_char = c_tail; // TODO ignore spaces, comments, ... at the end let tail = !c_tail.is_null() && unsafe { c_tail != c_sql.offset(len as isize) }; - Ok(Statement::new(conn, RawStatement::new(c_stmt, tail))) + Ok(Statement::new(conn, unsafe { + RawStatement::new(c_stmt, tail) + })) } pub fn changes(&mut self) -> usize { diff --git a/src/raw_statement.rs b/src/raw_statement.rs index 8d943ba..05634d6 100644 --- a/src/raw_statement.rs +++ b/src/raw_statement.rs @@ -10,7 +10,7 @@ use std::ptr; pub struct RawStatement(*mut ffi::sqlite3_stmt, bool); impl RawStatement { - pub fn new(stmt: *mut ffi::sqlite3_stmt, tail: bool) -> RawStatement { + pub unsafe fn new(stmt: *mut ffi::sqlite3_stmt, tail: bool) -> RawStatement { RawStatement(stmt, tail) } @@ -64,10 +64,10 @@ impl RawStatement { let mut rc; loop { rc = unsafe { ffi::sqlite3_step(self.0) }; - if !unlock_notify::is_locked(db, rc) { + if unsafe { !unlock_notify::is_locked(db, rc) } { break; } - rc = unlock_notify::wait_for_unlock_notify(db); + rc = unsafe { unlock_notify::wait_for_unlock_notify(db) }; if rc != ffi::SQLITE_OK { break; } diff --git a/src/statement.rs b/src/statement.rs index 942fbe9..2c3c14e 100644 --- a/src/statement.rs +++ b/src/statement.rs @@ -619,7 +619,7 @@ impl Statement<'_> { } fn finalize_(&mut self) -> Result<()> { - let mut stmt = RawStatement::new(ptr::null_mut(), false); + let mut stmt = unsafe { RawStatement::new(ptr::null_mut(), false) }; mem::swap(&mut stmt, &mut self.stmt); self.conn.decode_result(stmt.finalize()) } @@ -710,7 +710,7 @@ impl Statement<'_> { impl Into for Statement<'_> { fn into(mut self) -> RawStatement { - let mut stmt = RawStatement::new(ptr::null_mut(), false); + let mut stmt = unsafe { RawStatement::new(ptr::null_mut(), false) }; mem::swap(&mut stmt, &mut self.stmt); stmt } diff --git a/src/unlock_notify.rs b/src/unlock_notify.rs index 8b3d0fc..6f82ae2 100644 --- a/src/unlock_notify.rs +++ b/src/unlock_notify.rs @@ -53,10 +53,10 @@ unsafe extern "C" fn unlock_notify_cb(ap_arg: *mut *mut c_void, n_arg: c_int) { } #[cfg(feature = "unlock_notify")] -pub fn is_locked(db: *mut ffi::sqlite3, rc: c_int) -> bool { +pub unsafe fn is_locked(db: *mut ffi::sqlite3, rc: c_int) -> bool { rc == ffi::SQLITE_LOCKED_SHAREDCACHE || (rc & 0xFF) == ffi::SQLITE_LOCKED - && unsafe { ffi::sqlite3_extended_errcode(db) } == ffi::SQLITE_LOCKED_SHAREDCACHE + && ffi::sqlite3_extended_errcode(db) == ffi::SQLITE_LOCKED_SHAREDCACHE } /// This function assumes that an SQLite API call (either `sqlite3_prepare_v2()` @@ -72,16 +72,14 @@ pub fn is_locked(db: *mut ffi::sqlite3, rc: c_int) -> bool { /// this case the caller should not retry the operation and should roll /// back the current transaction (if any). #[cfg(feature = "unlock_notify")] -pub fn wait_for_unlock_notify(db: *mut ffi::sqlite3) -> c_int { +pub unsafe fn wait_for_unlock_notify(db: *mut ffi::sqlite3) -> c_int { let mut un = UnlockNotification::new(); /* Register for an unlock-notify callback. */ - let rc = unsafe { - ffi::sqlite3_unlock_notify( - db, - Some(unlock_notify_cb), - &mut un as *mut UnlockNotification as *mut c_void, - ) - }; + let rc = ffi::sqlite3_unlock_notify( + db, + Some(unlock_notify_cb), + &mut un as *mut UnlockNotification as *mut c_void, + ); debug_assert!( rc == ffi::SQLITE_LOCKED || rc == ffi::SQLITE_LOCKED_SHAREDCACHE || rc == ffi::SQLITE_OK ); @@ -92,12 +90,12 @@ pub fn wait_for_unlock_notify(db: *mut ffi::sqlite3) -> c_int { } #[cfg(not(feature = "unlock_notify"))] -pub fn is_locked(_db: *mut ffi::sqlite3, _rc: c_int) -> bool { +pub unsafe fn is_locked(_db: *mut ffi::sqlite3, _rc: c_int) -> bool { unreachable!() } #[cfg(not(feature = "unlock_notify"))] -pub fn wait_for_unlock_notify(_db: *mut ffi::sqlite3) -> c_int { +pub unsafe fn wait_for_unlock_notify(_db: *mut ffi::sqlite3) -> c_int { unreachable!() } From 8f7fc7d976884c91e99ae16f82ad89a811f18d8c Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Mon, 6 Apr 2020 19:53:55 -0700 Subject: [PATCH 2/2] Avoid using MaybeUninit for pointers --- src/inner_connection.rs | 20 +++------- src/lib.rs | 6 +-- src/session.rs | 88 ++++++++++++++++------------------------- 3 files changed, 42 insertions(+), 72 deletions(-) diff --git a/src/inner_connection.rs b/src/inner_connection.rs index 88e6957..2b5f4bb 100644 --- a/src/inner_connection.rs +++ b/src/inner_connection.rs @@ -1,5 +1,4 @@ use std::ffi::CString; -use std::mem::MaybeUninit; use std::os::raw::{c_char, c_int}; #[cfg(feature = "load_extension")] use std::path::Path; @@ -81,9 +80,8 @@ impl InnerConnection { }; unsafe { - let mut db = MaybeUninit::uninit(); - let r = ffi::sqlite3_open_v2(c_path.as_ptr(), db.as_mut_ptr(), flags.bits(), z_vfs); - let db: *mut ffi::sqlite3 = db.assume_init(); + let mut db: *mut ffi::sqlite3 = ptr::null_mut(); + let r = ffi::sqlite3_open_v2(c_path.as_ptr(), &mut db, flags.bits(), z_vfs); if r != ffi::SQLITE_OK { let e = if db.is_null() { error_from_sqlite_code(r, Some(c_path.to_string_lossy().to_string())) @@ -196,28 +194,22 @@ impl InnerConnection { pub fn load_extension(&self, dylib_path: &Path, entry_point: Option<&str>) -> Result<()> { let dylib_str = super::path_to_cstring(dylib_path)?; unsafe { - let mut errmsg = MaybeUninit::uninit(); + let mut errmsg: *mut c_char = ptr::null_mut(); let r = if let Some(entry_point) = entry_point { let c_entry = str_to_cstring(entry_point)?; ffi::sqlite3_load_extension( self.db, dylib_str.as_ptr(), c_entry.as_ptr(), - errmsg.as_mut_ptr(), + &mut errmsg, ) } else { - ffi::sqlite3_load_extension( - self.db, - dylib_str.as_ptr(), - ptr::null(), - errmsg.as_mut_ptr(), - ) + ffi::sqlite3_load_extension(self.db, dylib_str.as_ptr(), ptr::null(), &mut errmsg) }; if r == ffi::SQLITE_OK { Ok(()) } else { - let errmsg: *mut c_char = errmsg.assume_init(); - let message = super::errmsg_to_string(&*errmsg); + let message = super::errmsg_to_string(errmsg); ffi::sqlite3_free(errmsg as *mut ::std::os::raw::c_void); Err(error_from_sqlite_code(r, Some(message))) } diff --git a/src/lib.rs b/src/lib.rs index a428669..bb9382b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1028,25 +1028,23 @@ mod test { // statement first. let raw_stmt = { use super::str_to_cstring; - use std::mem::MaybeUninit; use std::os::raw::c_int; use std::ptr; let raw_db = db.db.borrow_mut().db; let sql = "SELECT 1"; - let mut raw_stmt = MaybeUninit::uninit(); + let mut raw_stmt: *mut ffi::sqlite3_stmt = ptr::null_mut(); let cstring = str_to_cstring(sql).unwrap(); let rc = unsafe { ffi::sqlite3_prepare_v2( raw_db, cstring.as_ptr(), (sql.len() + 1) as c_int, - raw_stmt.as_mut_ptr(), + &mut raw_stmt, ptr::null_mut(), ) }; assert_eq!(rc, ffi::SQLITE_OK); - let raw_stmt: *mut ffi::sqlite3_stmt = unsafe { raw_stmt.assume_init() }; raw_stmt }; diff --git a/src/session.rs b/src/session.rs index 479a232..34a53f4 100644 --- a/src/session.rs +++ b/src/session.rs @@ -4,7 +4,6 @@ use std::ffi::CStr; use std::io::{Read, Write}; use std::marker::PhantomData; -use std::mem::MaybeUninit; use std::os::raw::{c_char, c_int, c_uchar, c_void}; use std::panic::{catch_unwind, RefUnwindSafe}; use std::ptr; @@ -43,9 +42,8 @@ impl Session<'_> { let db = db.db.borrow_mut().db; - let mut s = MaybeUninit::uninit(); - check!(unsafe { ffi::sqlite3session_create(db, name.as_ptr(), s.as_mut_ptr()) }); - let s: *mut ffi::sqlite3_session = unsafe { s.assume_init() }; + let mut s: *mut ffi::sqlite3_session = ptr::null_mut(); + check!(unsafe { ffi::sqlite3session_create(db, name.as_ptr(), &mut s) }); Ok(Session { phantom: PhantomData, @@ -113,9 +111,8 @@ impl Session<'_> { /// Generate a Changeset pub fn changeset(&mut self) -> Result { let mut n = 0; - let mut cs = MaybeUninit::uninit(); - check!(unsafe { ffi::sqlite3session_changeset(self.s, &mut n, cs.as_mut_ptr()) }); - let cs: *mut c_void = unsafe { cs.assume_init() }; + let mut cs: *mut c_void = ptr::null_mut(); + check!(unsafe { ffi::sqlite3session_changeset(self.s, &mut n, &mut cs) }); Ok(Changeset { cs, n }) } @@ -135,9 +132,8 @@ impl Session<'_> { /// Generate a Patchset pub fn patchset(&mut self) -> Result { let mut n = 0; - let mut ps = MaybeUninit::uninit(); - check!(unsafe { ffi::sqlite3session_patchset(self.s, &mut n, ps.as_mut_ptr()) }); - let ps: *mut c_void = unsafe { ps.assume_init() }; + let mut ps: *mut c_void = ptr::null_mut(); + check!(unsafe { ffi::sqlite3session_patchset(self.s, &mut n, &mut ps) }); // TODO Validate: same struct Ok(Changeset { cs: ps, n }) } @@ -160,10 +156,11 @@ impl Session<'_> { let from = from.to_cstring()?; let table = str_to_cstring(table)?.as_ptr(); unsafe { - let mut errmsg = MaybeUninit::uninit(); - let r = ffi::sqlite3session_diff(self.s, from.as_ptr(), table, errmsg.as_mut_ptr()); + let mut errmsg = ptr::null_mut(); + let r = + ffi::sqlite3session_diff(self.s, from.as_ptr(), table, &mut errmsg as *mut *mut _); if r != ffi::SQLITE_OK { - let errmsg: *mut c_char = errmsg.assume_init(); + let errmsg: *mut c_char = errmsg; let message = errmsg_to_string(&*errmsg); ffi::sqlite3_free(errmsg as *mut ::std::os::raw::c_void); return Err(error_from_sqlite_code(r, Some(message))); @@ -258,17 +255,17 @@ impl Changeset { /// Invert a changeset pub fn invert(&self) -> Result { let mut n = 0; - let mut cs = MaybeUninit::uninit(); - check!(unsafe { ffi::sqlite3changeset_invert(self.n, self.cs, &mut n, cs.as_mut_ptr()) }); - let cs: *mut c_void = unsafe { cs.assume_init() }; + let mut cs = ptr::null_mut(); + check!(unsafe { + ffi::sqlite3changeset_invert(self.n, self.cs, &mut n, &mut cs as *mut *mut _) + }); Ok(Changeset { cs, n }) } /// Create an iterator to traverse a changeset pub fn iter(&self) -> Result> { - let mut it = MaybeUninit::uninit(); - check!(unsafe { ffi::sqlite3changeset_start(it.as_mut_ptr(), self.n, self.cs) }); - let it: *mut ffi::sqlite3_changeset_iter = unsafe { it.assume_init() }; + let mut it = ptr::null_mut(); + check!(unsafe { ffi::sqlite3changeset_start(&mut it as *mut *mut _, self.n, self.cs) }); Ok(ChangesetIter { phantom: PhantomData, it, @@ -279,11 +276,10 @@ impl Changeset { /// Concatenate two changeset objects pub fn concat(a: &Changeset, b: &Changeset) -> Result { let mut n = 0; - let mut cs = MaybeUninit::uninit(); + let mut cs = ptr::null_mut(); check!(unsafe { - ffi::sqlite3changeset_concat(a.n, a.cs, b.n, b.cs, &mut n, cs.as_mut_ptr()) + ffi::sqlite3changeset_concat(a.n, a.cs, b.n, b.cs, &mut n, &mut cs as *mut *mut _) }); - let cs: *mut c_void = unsafe { cs.assume_init() }; Ok(Changeset { cs, n }) } } @@ -307,15 +303,14 @@ pub struct ChangesetIter<'changeset> { impl ChangesetIter<'_> { /// Create an iterator on `input` pub fn start_strm<'input>(input: &&'input mut dyn Read) -> Result> { - let mut it = MaybeUninit::uninit(); + let mut it = ptr::null_mut(); check!(unsafe { ffi::sqlite3changeset_start_strm( - it.as_mut_ptr(), + &mut it as *mut *mut _, Some(x_input), input as *const &mut dyn Read as *mut c_void, ) }); - let it: *mut ffi::sqlite3_changeset_iter = unsafe { it.assume_init() }; Ok(ChangesetIter { phantom: PhantomData, it, @@ -396,13 +391,12 @@ impl ChangesetItem { /// `SQLITE_CHANGESET_CONFLICT` conflict handler callback. pub fn conflict(&self, col: usize) -> Result> { unsafe { - let mut p_value = MaybeUninit::uninit(); + let mut p_value: *mut ffi::sqlite3_value = ptr::null_mut(); check!(ffi::sqlite3changeset_conflict( self.it, col as i32, - p_value.as_mut_ptr() + &mut p_value, )); - let p_value: *mut ffi::sqlite3_value = p_value.assume_init(); Ok(ValueRef::from_value(p_value)) } } @@ -425,13 +419,8 @@ impl ChangesetItem { /// `SQLITE_INSERT`. pub fn new_value(&self, col: usize) -> Result> { unsafe { - let mut p_value = MaybeUninit::uninit(); - check!(ffi::sqlite3changeset_new( - self.it, - col as i32, - p_value.as_mut_ptr() - )); - let p_value: *mut ffi::sqlite3_value = p_value.assume_init(); + let mut p_value: *mut ffi::sqlite3_value = ptr::null_mut(); + check!(ffi::sqlite3changeset_new(self.it, col as i32, &mut p_value,)); Ok(ValueRef::from_value(p_value)) } } @@ -442,13 +431,8 @@ impl ChangesetItem { /// `SQLITE_UPDATE`. pub fn old_value(&self, col: usize) -> Result> { unsafe { - let mut p_value = MaybeUninit::uninit(); - check!(ffi::sqlite3changeset_old( - self.it, - col as i32, - p_value.as_mut_ptr() - )); - let p_value: *mut ffi::sqlite3_value = p_value.assume_init(); + let mut p_value: *mut ffi::sqlite3_value = ptr::null_mut(); + check!(ffi::sqlite3changeset_old(self.it, col as i32, &mut p_value,)); Ok(ValueRef::from_value(p_value)) } } @@ -459,15 +443,14 @@ impl ChangesetItem { let mut code = 0; let mut indirect = 0; let tab = unsafe { - let mut pz_tab = MaybeUninit::uninit(); + let mut pz_tab: *const c_char = ptr::null(); check!(ffi::sqlite3changeset_op( self.it, - pz_tab.as_mut_ptr(), + &mut pz_tab, &mut number_of_columns, &mut code, &mut indirect )); - let pz_tab: *const c_char = pz_tab.assume_init(); CStr::from_ptr(pz_tab) }; let table_name = tab.to_str()?; @@ -483,13 +466,12 @@ impl ChangesetItem { pub fn pk(&self) -> Result<&[u8]> { let mut number_of_columns = 0; unsafe { - let mut pks = MaybeUninit::uninit(); + let mut pks: *mut c_uchar = ptr::null_mut(); check!(ffi::sqlite3changeset_pk( self.it, - pks.as_mut_ptr(), + &mut pks, &mut number_of_columns )); - let pks: *mut c_uchar = pks.assume_init(); Ok(from_raw_parts(pks, number_of_columns as usize)) } } @@ -503,9 +485,8 @@ pub struct Changegroup { impl Changegroup { pub fn new() -> Result { - let mut cg = MaybeUninit::uninit(); - check!(unsafe { ffi::sqlite3changegroup_new(cg.as_mut_ptr()) }); - let cg: *mut ffi::sqlite3_changegroup = unsafe { cg.assume_init() }; + let mut cg = ptr::null_mut(); + check!(unsafe { ffi::sqlite3changegroup_new(&mut cg) }); Ok(Changegroup { cg }) } @@ -531,9 +512,8 @@ impl Changegroup { /// Obtain a composite Changeset pub fn output(&mut self) -> Result { let mut n = 0; - let mut output = MaybeUninit::uninit(); - check!(unsafe { ffi::sqlite3changegroup_output(self.cg, &mut n, output.as_mut_ptr()) }); - let output: *mut c_void = unsafe { output.assume_init() }; + let mut output: *mut c_void = ptr::null_mut(); + check!(unsafe { ffi::sqlite3changegroup_output(self.cg, &mut n, &mut output) }); Ok(Changeset { cs: output, n }) }