diff --git a/src/data/graph.rs b/src/data/graph.rs index dbebb2631..b3e1ff7af 100644 --- a/src/data/graph.rs +++ b/src/data/graph.rs @@ -146,12 +146,9 @@ fn index_twice(arr: &mut [T], a: usize, b: usize) -> Pair<&mut T> { } else if a == b { Pair::One(&mut arr[max(a, b)]) } else { - // safe because a, b are in bounds and distinct - unsafe { - let ar = &mut *(arr.get_unchecked_mut(a) as *mut _); - let br = &mut *(arr.get_unchecked_mut(b) as *mut _); - Pair::Both(ar, br) - } + // can't panic because a, b are in bounds and distinct + let [ar, br] = arr.get_disjoint_mut([a, b]).unwrap(); + Pair::Both(ar, br) } } diff --git a/src/dynamics/joint/multibody_joint/multibody.rs b/src/dynamics/joint/multibody_joint/multibody.rs index da3a097fe..3b2c7fb69 100644 --- a/src/dynamics/joint/multibody_joint/multibody.rs +++ b/src/dynamics/joint/multibody_joint/multibody.rs @@ -30,6 +30,11 @@ impl Force { } fn as_vector(&self) -> &SVector { + // SAFETY : this is safe because : + // - Force is repr(C) + // - Vector is repr(C) + // - AngVector is repr(C) or Real + // - total size in Reals is SPATIAL_DIM unsafe { core::mem::transmute(self) } } } diff --git a/src/dynamics/rigid_body_components.rs b/src/dynamics/rigid_body_components.rs index 439a784ba..68545d692 100644 --- a/src/dynamics/rigid_body_components.rs +++ b/src/dynamics/rigid_body_components.rs @@ -504,6 +504,7 @@ impl RigidBodyMassProps { #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[derive(Clone, Debug, Copy, PartialEq)] +#[repr(C)] /// The velocities of this rigid-body. pub struct RigidBodyVelocity { /// The linear velocity of the rigid-body. @@ -593,6 +594,11 @@ impl RigidBodyVelocity { #[inline] #[cfg(feature = "dim2")] pub fn as_vector(&self) -> &na::Vector3 { + // SAFETY : this is safe because : + // - RigidBodyVelocity is repr(C) + // - the vector types used are repr(C) + // - the only non vector type is Real + // - total size in Reals is 3 unsafe { core::mem::transmute(self) } } @@ -602,6 +608,11 @@ impl RigidBodyVelocity { #[inline] #[cfg(feature = "dim2")] pub fn as_vector_mut(&mut self) -> &mut na::Vector3 { + // SAFETY : this is safe because : + // - RigidBodyVelocity is repr(C) + // - the vector types used are repr(C) + // - the only non vector type is Real + // - total size in Reals is 3 unsafe { core::mem::transmute(self) } } @@ -611,6 +622,11 @@ impl RigidBodyVelocity { #[inline] #[cfg(feature = "dim3")] pub fn as_vector(&self) -> &na::Vector6 { + // SAFETY : this is safe because : + // - RigidBodyVelocity is repr(C) + // - the vector types used are repr(C) + // - the only non vector type is Real + // - total size in Reals is 6 unsafe { core::mem::transmute(self) } } @@ -620,6 +636,11 @@ impl RigidBodyVelocity { #[inline] #[cfg(feature = "dim3")] pub fn as_vector_mut(&mut self) -> &mut na::Vector6 { + // SAFETY : this is safe because : + // - RigidBodyVelocity is repr(C) + // - the vector types used are repr(C) + // - the only non vector type is Real + // - total size in Reals is 6 unsafe { core::mem::transmute(self) } } diff --git a/src/dynamics/solver/mod.rs b/src/dynamics/solver/mod.rs index 5a3ffbad4..daa27ec82 100644 --- a/src/dynamics/solver/mod.rs +++ b/src/dynamics/solver/mod.rs @@ -35,11 +35,6 @@ mod velocity_solver; // TODO: SAFETY: restrict with bytemuck::Zeroable to make this safe. pub unsafe fn reset_buffer(buffer: &mut Vec, len: usize) { buffer.clear(); - buffer.reserve(len); - unsafe { - // NOTE: writing zeros is faster than u8::MAX. - buffer.as_mut_ptr().write_bytes(0, len); - buffer.set_len(len); - } + buffer.resize_with(len, || unsafe { core::mem::zeroed() }) } diff --git a/src/utils/index_mut2.rs b/src/utils/index_mut2.rs index 6d81dbb82..e92974a78 100644 --- a/src/utils/index_mut2.rs +++ b/src/utils/index_mut2.rs @@ -25,14 +25,7 @@ pub trait IndexMut2: IndexMut { impl IndexMut2 for Vec { #[inline] fn index_mut2(&mut self, i: usize, j: usize) -> (&mut T, &mut T) { - assert!(i != j, "Unable to index the same element twice."); - assert!(i < self.len() && j < self.len(), "Index out of bounds."); - - unsafe { - let a = &mut *(self.get_unchecked_mut(i) as *mut _); - let b = &mut *(self.get_unchecked_mut(j) as *mut _); - (a, b) - } + <[T]>::index_mut2(self, i, j) } } @@ -42,10 +35,8 @@ impl IndexMut2 for [T] { assert!(i != j, "Unable to index the same element twice."); assert!(i < self.len() && j < self.len(), "Index out of bounds."); - unsafe { - let a = &mut *(self.get_unchecked_mut(i) as *mut _); - let b = &mut *(self.get_unchecked_mut(j) as *mut _); - (a, b) - } + // cannot panic, per the above checks + let [a, b] = self.get_disjoint_mut([i, j]).unwrap(); + (a, b) } }