Skip to content

Commit

Permalink
Apply unsafe_op_in_unsafe_fn lint
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Dec 23, 2023
1 parent 4b021eb commit 12c5eb5
Show file tree
Hide file tree
Showing 23 changed files with 164 additions and 139 deletions.
32 changes: 18 additions & 14 deletions crossbeam-channel/src/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1511,25 +1511,29 @@ impl<T> SelectHandle for Receiver<T> {

/// Writes a message into the channel.
pub(crate) unsafe fn write<T>(s: &Sender<T>, token: &mut Token, msg: T) -> Result<(), T> {
match &s.flavor {
SenderFlavor::Array(chan) => chan.write(token, msg),
SenderFlavor::List(chan) => chan.write(token, msg),
SenderFlavor::Zero(chan) => chan.write(token, msg),
unsafe {
match &s.flavor {
SenderFlavor::Array(chan) => chan.write(token, msg),
SenderFlavor::List(chan) => chan.write(token, msg),
SenderFlavor::Zero(chan) => chan.write(token, msg),
}
}
}

/// Reads a message from the channel.
pub(crate) unsafe fn read<T>(r: &Receiver<T>, token: &mut Token) -> Result<T, ()> {
match &r.flavor {
ReceiverFlavor::Array(chan) => chan.read(token),
ReceiverFlavor::List(chan) => chan.read(token),
ReceiverFlavor::Zero(chan) => chan.read(token),
ReceiverFlavor::At(chan) => {
mem::transmute_copy::<Result<Instant, ()>, Result<T, ()>>(&chan.read(token))
}
ReceiverFlavor::Tick(chan) => {
mem::transmute_copy::<Result<Instant, ()>, Result<T, ()>>(&chan.read(token))
unsafe {
match &r.flavor {
ReceiverFlavor::Array(chan) => chan.read(token),
ReceiverFlavor::List(chan) => chan.read(token),
ReceiverFlavor::Zero(chan) => chan.read(token),
ReceiverFlavor::At(chan) => {
mem::transmute_copy::<Result<Instant, ()>, Result<T, ()>>(&chan.read(token))
}
ReceiverFlavor::Tick(chan) => {
mem::transmute_copy::<Result<Instant, ()>, Result<T, ()>>(&chan.read(token))
}
ReceiverFlavor::Never(chan) => chan.read(token),
}
ReceiverFlavor::Never(chan) => chan.read(token),
}
}
4 changes: 2 additions & 2 deletions crossbeam-channel/src/counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl<C> Sender<C> {
disconnect(&self.counter().chan);

if self.counter().destroy.swap(true, Ordering::AcqRel) {
drop(Box::from_raw(self.counter));
drop(unsafe { Box::from_raw(self.counter) });
}
}
}
Expand Down Expand Up @@ -123,7 +123,7 @@ impl<C> Receiver<C> {
disconnect(&self.counter().chan);

if self.counter().destroy.swap(true, Ordering::AcqRel) {
drop(Box::from_raw(self.counter));
drop(unsafe { Box::from_raw(self.counter) });
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions crossbeam-channel/src/flavors/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,10 @@ impl<T> Channel<T> {
return Err(msg);
}

let slot: &Slot<T> = &*token.array.slot.cast::<Slot<T>>();
let slot: &Slot<T> = unsafe { &*token.array.slot.cast::<Slot<T>>() };

// Write the message into the slot and update the stamp.
slot.msg.get().write(MaybeUninit::new(msg));
unsafe { slot.msg.get().write(MaybeUninit::new(msg)) }
slot.stamp.store(token.array.stamp, Ordering::Release);

// Wake a sleeping receiver.
Expand Down Expand Up @@ -307,10 +307,10 @@ impl<T> Channel<T> {
return Err(());
}

let slot: &Slot<T> = &*token.array.slot.cast::<Slot<T>>();
let slot: &Slot<T> = unsafe { &*token.array.slot.cast::<Slot<T>>() };

// Read the message from the slot and update the stamp.
let msg = slot.msg.get().read().assume_init();
let msg = unsafe { slot.msg.get().read().assume_init() };
slot.stamp.store(token.array.stamp, Ordering::Release);

// Wake a sleeping sender.
Expand Down
22 changes: 12 additions & 10 deletions crossbeam-channel/src/flavors/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl<T> Block<T> {
// It is not necessary to set the `DESTROY` bit in the last slot because that slot has
// begun destruction of the block.
for i in start..BLOCK_CAP - 1 {
let slot = (*this).slots.get_unchecked(i);
let slot = unsafe { (*this).slots.get_unchecked(i) };

// Mark the `DESTROY` bit if a thread is still using the slot.
if slot.state.load(Ordering::Acquire) & READ == 0
Expand All @@ -112,7 +112,7 @@ impl<T> Block<T> {
}

// No thread is using the block, now it is safe to destroy it.
drop(Box::from_raw(this));
drop(unsafe { Box::from_raw(this) });
}
}

Expand Down Expand Up @@ -287,8 +287,8 @@ impl<T> Channel<T> {
// Write the message into the slot.
let block = token.list.block.cast::<Block<T>>();
let offset = token.list.offset;
let slot = (*block).slots.get_unchecked(offset);
slot.msg.get().write(MaybeUninit::new(msg));
let slot = unsafe { (*block).slots.get_unchecked(offset) };
unsafe { slot.msg.get().write(MaybeUninit::new(msg)) }
slot.state.fetch_or(WRITE, Ordering::Release);

// Wake a sleeping receiver.
Expand Down Expand Up @@ -391,16 +391,18 @@ impl<T> Channel<T> {
// Read the message.
let block = token.list.block as *mut Block<T>;
let offset = token.list.offset;
let slot = (*block).slots.get_unchecked(offset);
let slot = unsafe { (*block).slots.get_unchecked(offset) };
slot.wait_write();
let msg = slot.msg.get().read().assume_init();
let msg = unsafe { slot.msg.get().read().assume_init() };

// Destroy the block if we've reached the end, or if another thread wanted to destroy but
// couldn't because we were busy reading from the slot.
if offset + 1 == BLOCK_CAP {
Block::destroy(block, 0);
} else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 {
Block::destroy(block, offset + 1);
unsafe {
if offset + 1 == BLOCK_CAP {
Block::destroy(block, 0);
} else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 {
Block::destroy(block, offset + 1);
}
}

Ok(msg)
Expand Down
12 changes: 6 additions & 6 deletions crossbeam-channel/src/flavors/zero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ impl<T> Channel<T> {
return Err(msg);
}

let packet = &*(token.zero.0 as *const Packet<T>);
packet.msg.get().write(Some(msg));
let packet = unsafe { &*(token.zero.0 as *const Packet<T>) };
unsafe { packet.msg.get().write(Some(msg)) }
packet.ready.store(true, Ordering::Release);
Ok(())
}
Expand Down Expand Up @@ -176,21 +176,21 @@ impl<T> Channel<T> {
return Err(());
}

let packet = &*(token.zero.0 as *const Packet<T>);
let packet = unsafe { &*(token.zero.0 as *const Packet<T>) };

if packet.on_stack {
// The message has been in the packet from the beginning, so there is no need to wait
// for it. However, after reading the message, we need to set `ready` to `true` in
// order to signal that the packet can be destroyed.
let msg = packet.msg.get().replace(None).unwrap();
let msg = unsafe { packet.msg.get().replace(None).unwrap() };
packet.ready.store(true, Ordering::Release);
Ok(msg)
} else {
// Wait until the message becomes available, then read it and destroy the
// heap-allocated packet.
packet.wait_ready();
let msg = packet.msg.get().replace(None).unwrap();
drop(Box::from_raw(token.zero.0.cast::<Packet<T>>()));
let msg = unsafe { packet.msg.get().replace(None).unwrap() };
drop(unsafe { Box::from_raw(token.zero.0.cast::<Packet<T>>()) });
Ok(msg)
}
}
Expand Down
2 changes: 1 addition & 1 deletion crossbeam-channel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@
allow(dead_code, unused_assignments, unused_variables)
)
))]
#![warn(missing_docs)]
#![warn(missing_docs, unsafe_op_in_unsafe_fn)]
#![cfg_attr(not(feature = "std"), no_std)]

use cfg_if::cfg_if;
Expand Down
16 changes: 8 additions & 8 deletions crossbeam-deque/src/deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@ impl<T> Buffer<T> {

/// Deallocates the buffer.
unsafe fn dealloc(self) {
drop(Vec::from_raw_parts(self.ptr, 0, self.cap));
drop(unsafe { Vec::from_raw_parts(self.ptr, 0, self.cap) });
}

/// Returns a pointer to the task at the specified `index`.
unsafe fn at(&self, index: isize) -> *mut T {
// `self.cap` is always a power of two.
// We do all the loads at `MaybeUninit` because we might realize, after loading, that we
// don't actually have the right to access this memory.
self.ptr.offset(index & (self.cap - 1) as isize)
unsafe { self.ptr.offset(index & (self.cap - 1) as isize) }
}

/// Writes `task` into the specified `index`.
Expand All @@ -63,7 +63,7 @@ impl<T> Buffer<T> {
/// that would be more expensive and difficult to implement generically for all types `T`.
/// Hence, as a hack, we use a volatile write instead.
unsafe fn write(&self, index: isize, task: MaybeUninit<T>) {
ptr::write_volatile(self.at(index).cast::<MaybeUninit<T>>(), task)
unsafe { ptr::write_volatile(self.at(index).cast::<MaybeUninit<T>>(), task) }
}

/// Reads a task from the specified `index`.
Expand All @@ -73,7 +73,7 @@ impl<T> Buffer<T> {
/// that would be more expensive and difficult to implement generically for all types `T`.
/// Hence, as a hack, we use a volatile load instead.
unsafe fn read(&self, index: isize) -> MaybeUninit<T> {
ptr::read_volatile(self.at(index).cast::<MaybeUninit<T>>())
unsafe { ptr::read_volatile(self.at(index).cast::<MaybeUninit<T>>()) }
}
}

Expand Down Expand Up @@ -285,7 +285,7 @@ impl<T> Worker<T> {
let new = Buffer::alloc(new_cap);
let mut i = f;
while i != b {
ptr::copy_nonoverlapping(buffer.at(i), new.at(i), 1);
unsafe { ptr::copy_nonoverlapping(buffer.at(i), new.at(i), 1) }
i = i.wrapping_add(1);
}

Expand All @@ -299,7 +299,7 @@ impl<T> Worker<T> {
.swap(Owned::new(new).into_shared(guard), Ordering::Release, guard);

// Destroy the old buffer later.
guard.defer_unchecked(move || old.into_owned().into_box().dealloc());
unsafe { guard.defer_unchecked(move || old.into_owned().into_box().dealloc()) }

// If the buffer is very large, then flush the thread-local garbage in order to deallocate
// it as soon as possible.
Expand Down Expand Up @@ -1246,7 +1246,7 @@ impl<T> Block<T> {
// It is not necessary to set the `DESTROY` bit in the last slot because that slot has
// begun destruction of the block.
for i in (0..count).rev() {
let slot = (*this).slots.get_unchecked(i);
let slot = unsafe { (*this).slots.get_unchecked(i) };

// Mark the `DESTROY` bit if a thread is still using the slot.
if slot.state.load(Ordering::Acquire) & READ == 0
Expand All @@ -1258,7 +1258,7 @@ impl<T> Block<T> {
}

// No thread is using the block, now it is safe to destroy it.
drop(Box::from_raw(this));
drop(unsafe { Box::from_raw(this) });
}
}

Expand Down
2 changes: 1 addition & 1 deletion crossbeam-deque/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
allow(dead_code, unused_assignments, unused_variables)
)
))]
#![warn(missing_docs)]
#![warn(missing_docs, unsafe_op_in_unsafe_fn)]
#![cfg_attr(not(feature = "std"), no_std)]

use cfg_if::cfg_if;
Expand Down
Loading

0 comments on commit 12c5eb5

Please sign in to comment.