From 51a854cfeff998c4a6dd4dd54687bf9caf476384 Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Sun, 13 Feb 2022 03:30:02 +0000 Subject: [PATCH] address some clippy lints --- lib/src/annotation.rs | 2 +- lib/src/lib.rs | 4 +++ lib/src/replica.rs | 13 ++++----- lib/src/task.rs | 62 +++++++++++++++++++++---------------------- lib/src/uuid.rs | 6 ++--- lib/src/workingset.rs | 4 +-- 6 files changed, 46 insertions(+), 45 deletions(-) diff --git a/lib/src/annotation.rs b/lib/src/annotation.rs index a1fe78da5..dede87431 100644 --- a/lib/src/annotation.rs +++ b/lib/src/annotation.rs @@ -20,7 +20,7 @@ impl PassByValue for TCAnnotation { // SAFETY: // - any time_t value is valid // - time_t is copy, so ownership is not important - let entry = unsafe { self.entry.val_from_arg() }.unwrap(); + let entry = unsafe { libc::time_t::val_from_arg(self.entry) }.unwrap(); // SAFETY: // - self.description is not NULL (field docstring) // - self.description came from return_ptr in as_ctype diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 4c66ec76d..b6a8f2eec 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -2,6 +2,10 @@ // Not working yet in stable - https://github.com/rust-lang/rust-clippy/issues/8020 // #![warn(clippy::undocumented_unsafe_blocks)] +// docstrings for extern "C" functions are reflected into C, and do not benefit +// from safety docs. +#![allow(clippy::missing_safety_doc)] + mod traits; mod util; diff --git a/lib/src/replica.rs b/lib/src/replica.rs index 655120669..314f8d375 100644 --- a/lib/src/replica.rs +++ b/lib/src/replica.rs @@ -103,7 +103,7 @@ pub unsafe extern "C" fn tc_replica_new_in_memory() -> *mut TCReplica { /// Create a new TCReplica with an on-disk database having the given filename. On error, a string /// is written to the `error_out` parameter (if it is not NULL) and NULL is returned. #[no_mangle] -pub unsafe extern "C" fn tc_replica_new_on_disk<'a>( +pub unsafe extern "C" fn tc_replica_new_on_disk( path: *mut TCString, error_out: *mut *mut TCString, ) -> *mut TCReplica { @@ -169,7 +169,7 @@ pub unsafe extern "C" fn tc_replica_all_task_uuids(rep: *mut TCReplica) -> TCUui let uuids: Vec<_> = rep .all_task_uuids()? .drain(..) - .map(|uuid| TCUuid::return_val(uuid)) + .map(TCUuid::return_val) .collect(); Ok(TCUuidList::return_val(uuids)) }, @@ -265,10 +265,7 @@ pub unsafe extern "C" fn tc_replica_import_task_with_uuid( /// If undone_out is not NULL, then on success it is set to 1 if operations were undone, or 0 if /// there are no operations that can be done. #[no_mangle] -pub unsafe extern "C" fn tc_replica_undo<'a>( - rep: *mut TCReplica, - undone_out: *mut i32, -) -> TCResult { +pub unsafe extern "C" fn tc_replica_undo(rep: *mut TCReplica, undone_out: *mut i32) -> TCResult { wrap( rep, |rep| { @@ -323,9 +320,9 @@ pub unsafe extern "C" fn tc_replica_rebuild_working_set( /// to this function will return NULL. The rep pointer must not be NULL. The caller must free the /// returned string. #[no_mangle] -pub unsafe extern "C" fn tc_replica_error<'a>(rep: *mut TCReplica) -> *mut TCString<'static> { +pub unsafe extern "C" fn tc_replica_error(rep: *mut TCReplica) -> *mut TCString<'static> { // SAFETY: see type docstring - let rep: &'a mut TCReplica = unsafe { TCReplica::from_ptr_arg_ref_mut(rep) }; + let rep: &mut TCReplica = unsafe { TCReplica::from_ptr_arg_ref_mut(rep) }; if let Some(tcstring) = rep.error.take() { // SAFETY: see TCString docstring unsafe { tcstring.return_ptr() } diff --git a/lib/src/task.rs b/lib/src/task.rs index 24dc1fcfc..5a7a446fc 100644 --- a/lib/src/task.rs +++ b/lib/src/task.rs @@ -103,15 +103,15 @@ impl From for TCTask { /// Utility function to get a shared reference to the underlying Task. All Task getters /// are error-free, so this does not handle errors. -fn wrap<'a, T, F>(task: *mut TCTask, f: F) -> T +fn wrap(task: *mut TCTask, f: F) -> T where F: FnOnce(&Task) -> T, { // SAFETY: // - task is not null (promised by caller) - // - task outlives 'a (promised by caller) - let tctask: &'a mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) }; - let task: &'a Task = match &tctask.inner { + // - task outlives this function (promised by caller) + let tctask: &mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) }; + let task: &Task = match &tctask.inner { Inner::Immutable(t) => t, Inner::Mutable(t, _) => t.deref(), Inner::Invalid => unreachable!(), @@ -123,15 +123,15 @@ where /// Utility function to get a mutable reference to the underlying Task. The /// TCTask must be mutable. The inner function may use `?` syntax to return an /// error, which will be represented with the `err_value` returned to C. -fn wrap_mut<'a, T, F>(task: *mut TCTask, f: F, err_value: T) -> T +fn wrap_mut(task: *mut TCTask, f: F, err_value: T) -> T where F: FnOnce(&mut TaskMut) -> anyhow::Result, { // SAFETY: // - task is not null (promised by caller) - // - task outlives 'a (promised by caller) - let tctask: &'a mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) }; - let task: &'a mut TaskMut = match tctask.inner { + // - task outlives this function (promised by caller) + let tctask: &mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) }; + let task: &mut TaskMut = match tctask.inner { Inner::Immutable(_) => panic!("Task is immutable"), Inner::Mutable(ref mut t, _) => t, Inner::Invalid => unreachable!(), @@ -205,11 +205,11 @@ impl CList for TCTaskList { /// if (!success) { ... } /// ``` #[no_mangle] -pub unsafe extern "C" fn tc_task_to_mut<'a>(task: *mut TCTask, tcreplica: *mut TCReplica) { +pub unsafe extern "C" fn tc_task_to_mut(task: *mut TCTask, tcreplica: *mut TCReplica) { // SAFETY: // - task is not null (promised by caller) // - task outlives 'a (promised by caller) - let tctask: &'a mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) }; + let tctask: &mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) }; // SAFETY: // - tcreplica is not NULL (promised by caller) // - tcreplica lives until later call to to_immut via tc_task_to_immut (promised by caller, @@ -223,11 +223,11 @@ pub unsafe extern "C" fn tc_task_to_mut<'a>(task: *mut TCTask, tcreplica: *mut T /// /// The replica passed to `tc_task_to_mut` may be used freely after this call. #[no_mangle] -pub unsafe extern "C" fn tc_task_to_immut<'a>(task: *mut TCTask) { +pub unsafe extern "C" fn tc_task_to_immut(task: *mut TCTask) { // SAFETY: // - task is not null (promised by caller) // - task outlives 'a (promised by caller) - let tctask: &'a mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) }; + let tctask: &mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) }; tctask.to_immut(); } @@ -239,7 +239,7 @@ pub unsafe extern "C" fn tc_task_get_uuid(task: *mut TCTask) -> TCUuid { /// Get a task's status. #[no_mangle] -pub unsafe extern "C" fn tc_task_get_status<'a>(task: *mut TCTask) -> TCStatus { +pub unsafe extern "C" fn tc_task_get_status(task: *mut TCTask) -> TCStatus { wrap(task, |task| task.get_status().into()) } @@ -265,7 +265,7 @@ pub unsafe extern "C" fn tc_task_get_taskmap(task: *mut TCTask) -> TCKVList { /// Get a task's description, or NULL if the task cannot be represented as a C string (e.g., if it /// contains embedded NUL characters). #[no_mangle] -pub unsafe extern "C" fn tc_task_get_description<'a>(task: *mut TCTask) -> *mut TCString<'static> { +pub unsafe extern "C" fn tc_task_get_description(task: *mut TCTask) -> *mut TCString<'static> { wrap(task, |task| { let descr: TCString = task.get_description().into(); // SAFETY: see TCString docstring @@ -275,19 +275,19 @@ pub unsafe extern "C" fn tc_task_get_description<'a>(task: *mut TCTask) -> *mut /// Get the entry timestamp for a task (when it was created), or 0 if not set. #[no_mangle] -pub unsafe extern "C" fn tc_task_get_entry<'a>(task: *mut TCTask) -> libc::time_t { +pub unsafe extern "C" fn tc_task_get_entry(task: *mut TCTask) -> libc::time_t { wrap(task, |task| libc::time_t::as_ctype(task.get_entry())) } /// Get the wait timestamp for a task, or 0 if not set. #[no_mangle] -pub unsafe extern "C" fn tc_task_get_wait<'a>(task: *mut TCTask) -> libc::time_t { +pub unsafe extern "C" fn tc_task_get_wait(task: *mut TCTask) -> libc::time_t { wrap(task, |task| libc::time_t::as_ctype(task.get_wait())) } /// Get the modified timestamp for a task, or 0 if not set. #[no_mangle] -pub unsafe extern "C" fn tc_task_get_modified<'a>(task: *mut TCTask) -> libc::time_t { +pub unsafe extern "C" fn tc_task_get_modified(task: *mut TCTask) -> libc::time_t { wrap(task, |task| libc::time_t::as_ctype(task.get_modified())) } @@ -306,7 +306,7 @@ pub unsafe extern "C" fn tc_task_is_active(task: *mut TCTask) -> bool { /// Check if a task has the given tag. If the tag is invalid, this function will return false, as /// that (invalid) tag is not present. No error will be reported via `tc_task_error`. #[no_mangle] -pub unsafe extern "C" fn tc_task_has_tag<'a>(task: *mut TCTask, tag: *mut TCString) -> bool { +pub unsafe extern "C" fn tc_task_has_tag(task: *mut TCTask, tag: *mut TCString) -> bool { // SAFETY: see TCString docstring let tcstring = unsafe { TCString::take_from_ptr_arg(tag) }; wrap(task, |task| { @@ -323,7 +323,7 @@ pub unsafe extern "C" fn tc_task_has_tag<'a>(task: *mut TCTask, tag: *mut TCStri /// The caller must free the returned TCStringList instance. The TCStringList instance does not /// reference the task and the two may be freed in any order. #[no_mangle] -pub unsafe extern "C" fn tc_task_get_tags<'a>(task: *mut TCTask) -> TCStringList { +pub unsafe extern "C" fn tc_task_get_tags(task: *mut TCTask) -> TCStringList { wrap(task, |task| { let vec: Vec>> = task .get_tags() @@ -344,7 +344,7 @@ pub unsafe extern "C" fn tc_task_get_tags<'a>(task: *mut TCTask) -> TCStringList /// The caller must free the returned TCAnnotationList instance. The TCStringList instance does not /// reference the task and the two may be freed in any order. #[no_mangle] -pub unsafe extern "C" fn tc_task_get_annotations<'a>(task: *mut TCTask) -> TCAnnotationList { +pub unsafe extern "C" fn tc_task_get_annotations(task: *mut TCTask) -> TCAnnotationList { wrap(task, |task| { let vec: Vec = task .get_annotations() @@ -404,7 +404,7 @@ pub unsafe extern "C" fn tc_task_get_legacy_uda<'a>( /// /// Legacy UDAs are represented with an empty string in the ns field. #[no_mangle] -pub unsafe extern "C" fn tc_task_get_udas<'a>(task: *mut TCTask) -> TCUDAList { +pub unsafe extern "C" fn tc_task_get_udas(task: *mut TCTask) -> TCUDAList { wrap(task, |task| { let vec: Vec = task .get_udas() @@ -425,7 +425,7 @@ pub unsafe extern "C" fn tc_task_get_udas<'a>(task: *mut TCTask) -> TCUDAList { /// All TCUDAs in this list have a NULL ns field. The entire UDA key is /// included in the key field. #[no_mangle] -pub unsafe extern "C" fn tc_task_get_legacy_udas<'a>(task: *mut TCTask) -> TCUDAList { +pub unsafe extern "C" fn tc_task_get_legacy_udas(task: *mut TCTask) -> TCUDAList { wrap(task, |task| { let vec: Vec = task .get_legacy_udas() @@ -443,7 +443,7 @@ pub unsafe extern "C" fn tc_task_get_legacy_udas<'a>(task: *mut TCTask) -> TCUDA /// Set a mutable task's status. #[no_mangle] -pub unsafe extern "C" fn tc_task_set_status<'a>(task: *mut TCTask, status: TCStatus) -> TCResult { +pub unsafe extern "C" fn tc_task_set_status(task: *mut TCTask, status: TCStatus) -> TCResult { wrap_mut( task, |task| { @@ -456,7 +456,7 @@ pub unsafe extern "C" fn tc_task_set_status<'a>(task: *mut TCTask, status: TCSta /// Set a mutable task's description. #[no_mangle] -pub unsafe extern "C" fn tc_task_set_description<'a>( +pub unsafe extern "C" fn tc_task_set_description( task: *mut TCTask, description: *mut TCString, ) -> TCResult { @@ -640,7 +640,7 @@ pub unsafe extern "C" fn tc_task_remove_annotation(task: *mut TCTask, entry: i64 /// Set a UDA on a mutable task. #[no_mangle] -pub unsafe extern "C" fn tc_task_set_uda<'a>( +pub unsafe extern "C" fn tc_task_set_uda( task: *mut TCTask, ns: *mut TCString, key: *mut TCString, @@ -668,7 +668,7 @@ pub unsafe extern "C" fn tc_task_set_uda<'a>( /// Remove a UDA fraom a mutable task. #[no_mangle] -pub unsafe extern "C" fn tc_task_remove_uda<'a>( +pub unsafe extern "C" fn tc_task_remove_uda( task: *mut TCTask, ns: *mut TCString, key: *mut TCString, @@ -689,7 +689,7 @@ pub unsafe extern "C" fn tc_task_remove_uda<'a>( /// Set a legacy UDA on a mutable task. #[no_mangle] -pub unsafe extern "C" fn tc_task_set_legacy_uda<'a>( +pub unsafe extern "C" fn tc_task_set_legacy_uda( task: *mut TCTask, key: *mut TCString, value: *mut TCString, @@ -710,7 +710,7 @@ pub unsafe extern "C" fn tc_task_set_legacy_uda<'a>( /// Remove a UDA fraom a mutable task. #[no_mangle] -pub unsafe extern "C" fn tc_task_remove_legacy_uda<'a>( +pub unsafe extern "C" fn tc_task_remove_legacy_uda( task: *mut TCTask, key: *mut TCString, ) -> TCResult { @@ -730,11 +730,11 @@ pub unsafe extern "C" fn tc_task_remove_legacy_uda<'a>( /// to this function will return NULL. The task pointer must not be NULL. The caller must free the /// returned string. #[no_mangle] -pub unsafe extern "C" fn tc_task_error<'a>(task: *mut TCTask) -> *mut TCString<'static> { +pub unsafe extern "C" fn tc_task_error(task: *mut TCTask) -> *mut TCString<'static> { // SAFETY: // - task is not null (promised by caller) // - task outlives 'a (promised by caller) - let task: &'a mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) }; + let task: &mut TCTask = unsafe { TCTask::from_ptr_arg_ref_mut(task) }; if let Some(tcstring) = task.error.take() { unsafe { tcstring.return_ptr() } } else { @@ -747,7 +747,7 @@ pub unsafe extern "C" fn tc_task_error<'a>(task: *mut TCTask) -> *mut TCString<' /// /// If the task is currently mutable, it will first be made immutable. #[no_mangle] -pub unsafe extern "C" fn tc_task_free<'a>(task: *mut TCTask) { +pub unsafe extern "C" fn tc_task_free(task: *mut TCTask) { // SAFETY: // - rep is not NULL (promised by caller) // - caller will not use the TCTask after this (promised by caller) diff --git a/lib/src/uuid.rs b/lib/src/uuid.rs index f3d0528b3..9496e8b0b 100644 --- a/lib/src/uuid.rs +++ b/lib/src/uuid.rs @@ -75,7 +75,7 @@ impl CList for TCUuidList { /// Write the string representation of a TCUuid into the given buffer, which must be /// at least TC_UUID_STRING_BYTES long. No NUL terminator is added. #[no_mangle] -pub unsafe extern "C" fn tc_uuid_to_buf<'a>(tcuuid: TCUuid, buf: *mut libc::c_char) { +pub unsafe extern "C" fn tc_uuid_to_buf(tcuuid: TCUuid, buf: *mut libc::c_char) { debug_assert!(!buf.is_null()); // SAFETY: // - buf is valid for len bytes (by C convention) @@ -83,7 +83,7 @@ pub unsafe extern "C" fn tc_uuid_to_buf<'a>(tcuuid: TCUuid, buf: *mut libc::c_ch // - content of buf will not be mutated during the lifetime of this slice (lifetime // does not outlive this function call) // - the length of the buffer is less than isize::MAX (promised by caller) - let buf: &'a mut [u8] = unsafe { + let buf: &mut [u8] = unsafe { std::slice::from_raw_parts_mut(buf as *mut u8, ::uuid::adapter::Hyphenated::LENGTH) }; // SAFETY: @@ -107,7 +107,7 @@ pub unsafe extern "C" fn tc_uuid_to_str(tcuuid: TCUuid) -> *mut TCString<'static /// Parse the given string as a UUID. Returns TC_RESULT_ERROR on parse failure or if the given /// string is not valid. #[no_mangle] -pub unsafe extern "C" fn tc_uuid_from_str<'a>(s: *mut TCString, uuid_out: *mut TCUuid) -> TCResult { +pub unsafe extern "C" fn tc_uuid_from_str(s: *mut TCString, uuid_out: *mut TCUuid) -> TCResult { debug_assert!(!s.is_null()); debug_assert!(!uuid_out.is_null()); // SAFETY: see TCString docstring diff --git a/lib/src/workingset.rs b/lib/src/workingset.rs index 02780e50f..6e1e15b0f 100644 --- a/lib/src/workingset.rs +++ b/lib/src/workingset.rs @@ -18,14 +18,14 @@ impl From for TCWorkingSet { } /// Utility function to get a shared reference to the underlying WorkingSet. -fn wrap<'a, T, F>(ws: *mut TCWorkingSet, f: F) -> T +fn wrap(ws: *mut TCWorkingSet, f: F) -> T where F: FnOnce(&WorkingSet) -> T, { // SAFETY: // - ws is not null (promised by caller) // - ws outlives 'a (promised by caller) - let tcws: &'a TCWorkingSet = unsafe { TCWorkingSet::from_ptr_arg_ref(ws) }; + let tcws: &TCWorkingSet = unsafe { TCWorkingSet::from_ptr_arg_ref(ws) }; f(&tcws.0) }