Skip to content

Commit d96cb45

Browse files
Merge #822
822: Fix/suppress clippy lints on nightly r=Bromeon a=chitoyuu - Modified `LocalCell<T>` so the destructor is not called on a different thread. Allowed `clippy::non_send_fields_in_send_ty` otherwise. - Removed mentions of `if_then_panic` which is no longer a thing (`https://github.com/rust-lang/rust-clippy/pull/7810`). - A few other minor fixes. Co-authored-by: Chitose Yuuzaki <[email protected]>
2 parents 31e0ad8 + 6e7ed37 commit d96cb45

File tree

6 files changed

+29
-13
lines changed

6 files changed

+29
-13
lines changed

gdnative-bindings/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#![allow(unused_unsafe)]
66
// False positives on generated drops that enforce lifetime
77
#![allow(clippy::drop_copy)]
8+
// False positives on thread-safe singletons
9+
#![allow(clippy::non_send_fields_in_send_ty)]
810
// Disable non-critical lints for generated code
911
#![allow(clippy::style, clippy::complexity, clippy::perf)]
1012

gdnative-core/src/core_types/transform2d.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,7 @@ fn test_transform2d_behavior_impl() {
360360
let rotation_rust = new_transform_rust.rotation();
361361
let rotation_godot = unsafe { (api.godot_transform2d_get_rotation)(new_transform_rust.sys()) };
362362

363-
assert!(
364-
(rotation_rust - rotation_godot) < f32::EPSILON,
365-
"Rotation getters should return equal results"
366-
);
363+
approx::assert_relative_eq!(rotation_rust, rotation_godot);
367364

368365
let scale_rust = new_transform_rust.scale();
369366
let scale_godot =

gdnative-core/src/core_types/variant.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ impl Default for Variant {
623623
impl fmt::Debug for Variant {
624624
#[inline]
625625
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
626-
write!(f, "{:?}({})", self.get_type(), self.to_string())
626+
write!(f, "{:?}({})", self.get_type(), self)
627627
}
628628
}
629629

gdnative-core/src/export/user_data.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -522,10 +522,16 @@ impl<T> Clone for ArcData<T> {
522522
}
523523

524524
/// User-data wrapper analogous to a `Arc<RefCell<T>>`, that is restricted to the thread
525-
/// where it was originally created.
525+
/// where it was originally created. The destructor of `T` is not guaranteed to be run if
526+
/// this is actually shared across multiple threads.
526527
///
527528
/// This works by checking `ThreadId` before touching the underlying reference. If the id
528529
/// doesn't match the original thread, `map` and `map_mut` will return an error.
530+
///
531+
/// Since it isn't possible to control where the last reference is dropped, the destructor
532+
/// isn't run if the last reference is dropped on a different thread than the one where the
533+
/// wrapper was originally created. To ensure that values are cleaned up properly, keep the
534+
/// game single-threaded, or use a real thread-safe wrapper such as [`MutexData`] instead.
529535
#[derive(Debug)]
530536
pub struct LocalCellData<T> {
531537
inner: Arc<local_cell::LocalCell<T>>,
@@ -535,12 +541,23 @@ pub use self::local_cell::LocalCellError;
535541

536542
mod local_cell {
537543
use std::cell::{Ref, RefCell, RefMut};
544+
use std::mem::ManuallyDrop;
538545
use std::thread::{self, ThreadId};
539546

540547
#[derive(Debug)]
541548
pub struct LocalCell<T> {
542549
thread_id: ThreadId,
543-
cell: RefCell<T>,
550+
cell: RefCell<ManuallyDrop<T>>,
551+
}
552+
553+
impl<T> Drop for LocalCell<T> {
554+
fn drop(&mut self) {
555+
if self.thread_id == thread::current().id() {
556+
unsafe {
557+
ManuallyDrop::drop(self.cell.get_mut());
558+
}
559+
}
560+
}
544561
}
545562

546563
/// Error indicating that a borrow has failed.
@@ -578,12 +595,12 @@ mod local_cell {
578595
pub fn new(val: T) -> Self {
579596
LocalCell {
580597
thread_id: thread::current().id(),
581-
cell: RefCell::new(val),
598+
cell: RefCell::new(ManuallyDrop::new(val)),
582599
}
583600
}
584601

585602
#[inline]
586-
fn inner(&self) -> Result<&RefCell<T>, LocalCellError> {
603+
fn inner(&self) -> Result<&RefCell<ManuallyDrop<T>>, LocalCellError> {
587604
let current = thread::current().id();
588605

589606
if self.thread_id == current {
@@ -597,13 +614,13 @@ mod local_cell {
597614
}
598615

599616
#[inline]
600-
pub fn try_borrow(&self) -> Result<Ref<T>, LocalCellError> {
617+
pub fn try_borrow(&self) -> Result<Ref<ManuallyDrop<T>>, LocalCellError> {
601618
let inner = self.inner()?;
602619
inner.try_borrow().map_err(|_| LocalCellError::BorrowFailed)
603620
}
604621

605622
#[inline]
606-
pub fn try_borrow_mut(&self) -> Result<RefMut<T>, LocalCellError> {
623+
pub fn try_borrow_mut(&self) -> Result<RefMut<ManuallyDrop<T>>, LocalCellError> {
607624
let inner = self.inner()?;
608625
inner
609626
.try_borrow_mut()

gdnative-core/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#![allow(
2424
clippy::transmute_ptr_to_ptr,
2525
clippy::missing_safety_doc,
26-
clippy::if_then_panic
26+
clippy::non_send_fields_in_send_ty
2727
)]
2828
#![cfg_attr(feature = "gd_test", allow(clippy::blacklisted_name))]
2929

test/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![allow(clippy::blacklisted_name, clippy::if_then_panic)]
1+
#![allow(clippy::blacklisted_name)]
22

33
use gdnative::prelude::*;
44

0 commit comments

Comments
 (0)