mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
gpui: Remove some unnecessary unsafe code (#40483)
Release Notes: - N/A *or* Added/Fixed/Improved ...
This commit is contained in:
parent
eb3f9b0ea3
commit
b59a3bbd49
10 changed files with 76 additions and 92 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -7390,6 +7390,7 @@ dependencies = [
|
|||
"parking",
|
||||
"parking_lot",
|
||||
"pathfinder_geometry",
|
||||
"pin-project",
|
||||
"postage",
|
||||
"pretty_assertions",
|
||||
"profiling",
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ waker-fn = "1.2.0"
|
|||
lyon = "1.0"
|
||||
workspace-hack.workspace = true
|
||||
libc.workspace = true
|
||||
pin-project = "1.1.10"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
block = "0.1"
|
||||
|
|
|
|||
|
|
@ -378,11 +378,9 @@ pub struct Entity<T> {
|
|||
#[deref]
|
||||
#[deref_mut]
|
||||
pub(crate) any_entity: AnyEntity,
|
||||
pub(crate) entity_type: PhantomData<T>,
|
||||
pub(crate) entity_type: PhantomData<fn(T) -> T>,
|
||||
}
|
||||
|
||||
unsafe impl<T> Send for Entity<T> {}
|
||||
unsafe impl<T> Sync for Entity<T> {}
|
||||
impl<T> Sealed for Entity<T> {}
|
||||
|
||||
impl<T: 'static> Entity<T> {
|
||||
|
|
@ -657,7 +655,7 @@ pub struct WeakEntity<T> {
|
|||
#[deref]
|
||||
#[deref_mut]
|
||||
any_entity: AnyWeakEntity,
|
||||
entity_type: PhantomData<T>,
|
||||
entity_type: PhantomData<fn(T) -> T>,
|
||||
}
|
||||
|
||||
impl<T> std::fmt::Debug for WeakEntity<T> {
|
||||
|
|
@ -669,9 +667,6 @@ impl<T> std::fmt::Debug for WeakEntity<T> {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<T> Send for WeakEntity<T> {}
|
||||
unsafe impl<T> Sync for WeakEntity<T> {}
|
||||
|
||||
impl<T> Clone for WeakEntity<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
|
|
|
|||
|
|
@ -888,7 +888,9 @@ impl VisualTestContext {
|
|||
// safety: on_quit will be called after the test has finished.
|
||||
// the executor will ensure that all tasks related to the test have stopped.
|
||||
// so there is no way for cx to be accessed after on_quit is called.
|
||||
let cx = Box::leak(unsafe { Box::from_raw(ptr) });
|
||||
// todo: This is unsound under stacked borrows (also tree borrows probably?)
|
||||
// the mutable reference invalidates `ptr` which is later used in the closure
|
||||
let cx = unsafe { &mut *ptr };
|
||||
cx.on_quit(move || unsafe {
|
||||
drop(Box::from_raw(ptr));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,9 +15,7 @@ struct ArenaElement {
|
|||
impl Drop for ArenaElement {
|
||||
#[inline(always)]
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
(self.drop)(self.value);
|
||||
}
|
||||
unsafe { (self.drop)(self.value) };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -40,33 +38,29 @@ impl Drop for Chunk {
|
|||
|
||||
impl Chunk {
|
||||
fn new(chunk_size: NonZeroUsize) -> Self {
|
||||
unsafe {
|
||||
// this only fails if chunk_size is unreasonably huge
|
||||
let layout = alloc::Layout::from_size_align(chunk_size.get(), 1).unwrap();
|
||||
let start = alloc::alloc(layout);
|
||||
if start.is_null() {
|
||||
handle_alloc_error(layout);
|
||||
}
|
||||
let end = start.add(chunk_size.get());
|
||||
Self {
|
||||
start,
|
||||
end,
|
||||
offset: start,
|
||||
}
|
||||
// this only fails if chunk_size is unreasonably huge
|
||||
let layout = alloc::Layout::from_size_align(chunk_size.get(), 1).unwrap();
|
||||
let start = unsafe { alloc::alloc(layout) };
|
||||
if start.is_null() {
|
||||
handle_alloc_error(layout);
|
||||
}
|
||||
let end = unsafe { start.add(chunk_size.get()) };
|
||||
Self {
|
||||
start,
|
||||
end,
|
||||
offset: start,
|
||||
}
|
||||
}
|
||||
|
||||
fn allocate(&mut self, layout: alloc::Layout) -> Option<NonNull<u8>> {
|
||||
unsafe {
|
||||
let aligned = self.offset.add(self.offset.align_offset(layout.align()));
|
||||
let next = aligned.add(layout.size());
|
||||
let aligned = unsafe { self.offset.add(self.offset.align_offset(layout.align())) };
|
||||
let next = unsafe { aligned.add(layout.size()) };
|
||||
|
||||
if next <= self.end {
|
||||
self.offset = next;
|
||||
NonNull::new(aligned)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
if next <= self.end {
|
||||
self.offset = next;
|
||||
NonNull::new(aligned)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -122,54 +116,48 @@ impl Arena {
|
|||
where
|
||||
F: FnOnce() -> T,
|
||||
{
|
||||
unsafe {
|
||||
ptr::write(ptr, f());
|
||||
}
|
||||
unsafe { ptr::write(ptr, f()) };
|
||||
}
|
||||
|
||||
unsafe fn drop<T>(ptr: *mut u8) {
|
||||
unsafe {
|
||||
std::ptr::drop_in_place(ptr.cast::<T>());
|
||||
}
|
||||
unsafe { std::ptr::drop_in_place(ptr.cast::<T>()) };
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let layout = alloc::Layout::new::<T>();
|
||||
let mut current_chunk = &mut self.chunks[self.current_chunk_index];
|
||||
let ptr = if let Some(ptr) = current_chunk.allocate(layout) {
|
||||
let layout = alloc::Layout::new::<T>();
|
||||
let mut current_chunk = &mut self.chunks[self.current_chunk_index];
|
||||
let ptr = if let Some(ptr) = current_chunk.allocate(layout) {
|
||||
ptr.as_ptr()
|
||||
} else {
|
||||
self.current_chunk_index += 1;
|
||||
if self.current_chunk_index >= self.chunks.len() {
|
||||
self.chunks.push(Chunk::new(self.chunk_size));
|
||||
assert_eq!(self.current_chunk_index, self.chunks.len() - 1);
|
||||
log::trace!(
|
||||
"increased element arena capacity to {}kb",
|
||||
self.capacity() / 1024,
|
||||
);
|
||||
}
|
||||
current_chunk = &mut self.chunks[self.current_chunk_index];
|
||||
if let Some(ptr) = current_chunk.allocate(layout) {
|
||||
ptr.as_ptr()
|
||||
} else {
|
||||
self.current_chunk_index += 1;
|
||||
if self.current_chunk_index >= self.chunks.len() {
|
||||
self.chunks.push(Chunk::new(self.chunk_size));
|
||||
assert_eq!(self.current_chunk_index, self.chunks.len() - 1);
|
||||
log::trace!(
|
||||
"increased element arena capacity to {}kb",
|
||||
self.capacity() / 1024,
|
||||
);
|
||||
}
|
||||
current_chunk = &mut self.chunks[self.current_chunk_index];
|
||||
if let Some(ptr) = current_chunk.allocate(layout) {
|
||||
ptr.as_ptr()
|
||||
} else {
|
||||
panic!(
|
||||
"Arena chunk_size of {} is too small to allocate {} bytes",
|
||||
self.chunk_size,
|
||||
layout.size()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
inner_writer(ptr.cast(), f);
|
||||
self.elements.push(ArenaElement {
|
||||
value: ptr,
|
||||
drop: drop::<T>,
|
||||
});
|
||||
|
||||
ArenaBox {
|
||||
ptr: ptr.cast(),
|
||||
valid: self.valid.clone(),
|
||||
panic!(
|
||||
"Arena chunk_size of {} is too small to allocate {} bytes",
|
||||
self.chunk_size,
|
||||
layout.size()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
unsafe { inner_writer(ptr.cast(), f) };
|
||||
self.elements.push(ArenaElement {
|
||||
value: ptr,
|
||||
drop: drop::<T>,
|
||||
});
|
||||
|
||||
ArenaBox {
|
||||
ptr: ptr.cast(),
|
||||
valid: self.valid.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -525,9 +525,7 @@ where
|
|||
"local task dropped by a thread that didn't spawn it. Task spawned at {}",
|
||||
self.location
|
||||
);
|
||||
unsafe {
|
||||
ManuallyDrop::drop(&mut self.inner);
|
||||
}
|
||||
unsafe { ManuallyDrop::drop(&mut self.inner) };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -348,8 +348,6 @@ impl Debug for DisplayId {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for DisplayId {}
|
||||
|
||||
/// Which part of the window to resize
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ResizeEdge {
|
||||
|
|
|
|||
|
|
@ -69,9 +69,7 @@ impl TaffyLayoutEngine {
|
|||
} else {
|
||||
self.taffy
|
||||
// This is safe because LayoutId is repr(transparent) to taffy::tree::NodeId.
|
||||
.new_with_children(taffy_style, unsafe {
|
||||
std::mem::transmute::<&[LayoutId], &[taffy::NodeId]>(children)
|
||||
})
|
||||
.new_with_children(taffy_style, LayoutId::to_taffy_slice(children))
|
||||
.expect(EXPECT_MESSAGE)
|
||||
.into()
|
||||
}
|
||||
|
|
@ -265,6 +263,13 @@ impl TaffyLayoutEngine {
|
|||
#[repr(transparent)]
|
||||
pub struct LayoutId(NodeId);
|
||||
|
||||
impl LayoutId {
|
||||
fn to_taffy_slice(node_ids: &[Self]) -> &[taffy::NodeId] {
|
||||
// SAFETY: LayoutId is repr(transparent) to taffy::tree::NodeId.
|
||||
unsafe { std::mem::transmute::<&[LayoutId], &[taffy::NodeId]>(node_ids) }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::hash::Hash for LayoutId {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
u64::from(self.0).hash(state);
|
||||
|
|
|
|||
|
|
@ -83,8 +83,11 @@ impl<T: Future> FutureExt for T {
|
|||
}
|
||||
}
|
||||
|
||||
#[pin_project::pin_project]
|
||||
pub struct WithTimeout<T> {
|
||||
#[pin]
|
||||
future: T,
|
||||
#[pin]
|
||||
timer: Task<()>,
|
||||
}
|
||||
|
||||
|
|
@ -97,15 +100,11 @@ impl<T: Future> Future for WithTimeout<T> {
|
|||
type Output = Result<T::Output, Timeout>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut task::Context) -> task::Poll<Self::Output> {
|
||||
// SAFETY: the fields of Timeout are private and we never move the future ourselves
|
||||
// And its already pinned since we are being polled (all futures need to be pinned to be polled)
|
||||
let this = unsafe { &raw mut *self.get_unchecked_mut() };
|
||||
let future = unsafe { Pin::new_unchecked(&mut (*this).future) };
|
||||
let timer = unsafe { Pin::new_unchecked(&mut (*this).timer) };
|
||||
let this = self.project();
|
||||
|
||||
if let task::Poll::Ready(output) = future.poll(cx) {
|
||||
if let task::Poll::Ready(output) = this.future.poll(cx) {
|
||||
task::Poll::Ready(Ok(output))
|
||||
} else if timer.poll(cx).is_ready() {
|
||||
} else if this.timer.poll(cx).is_ready() {
|
||||
task::Poll::Ready(Err(Timeout))
|
||||
} else {
|
||||
task::Poll::Pending
|
||||
|
|
|
|||
|
|
@ -4650,7 +4650,7 @@ pub struct WindowHandle<V> {
|
|||
#[deref]
|
||||
#[deref_mut]
|
||||
pub(crate) any_handle: AnyWindowHandle,
|
||||
state_type: PhantomData<V>,
|
||||
state_type: PhantomData<fn(V) -> V>,
|
||||
}
|
||||
|
||||
impl<V> Debug for WindowHandle<V> {
|
||||
|
|
@ -4786,9 +4786,6 @@ impl<V: 'static> From<WindowHandle<V>> for AnyWindowHandle {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl<V> Send for WindowHandle<V> {}
|
||||
unsafe impl<V> Sync for WindowHandle<V> {}
|
||||
|
||||
/// A handle to a window with any root view type, which can be downcast to a window with a specific root view type.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct AnyWindowHandle {
|
||||
|
|
|
|||
Loading…
Reference in a new issue