@@ -215,7 +215,9 @@ struct SlotPtr(*mut Option<u8>);
215
215
impl SlotPtr {
216
216
/// Replace the value of this slot with `new_value`, and return
217
217
/// the old value.
218
- fn replace (
218
+ ///
219
+ /// SAFETY: the pointer in this `SlotPtr` must still be valid.
220
+ unsafe fn replace (
219
221
& mut self ,
220
222
new_value : Option < u8 > ,
221
223
_cs : critical_section:: CriticalSection ,
@@ -314,8 +316,10 @@ impl<T, const N: usize> Sender<'_, T, N> {
314
316
// Potentially unnecessary c-s because our link was already popped, so there
315
317
// is no way for anything else to access the free slot ptr. Gotta think
316
318
// about this a bit more...
319
+ //
320
+ // SAFETY(replace): the data pointed to by `free_slot_ptr2` is still alive.
317
321
critical_section:: with ( |cs| {
318
- if let Some ( freed_slot) = free_slot_ptr2. replace ( None , cs) {
322
+ if let Some ( freed_slot) = unsafe { free_slot_ptr2. replace ( None , cs) } {
319
323
debug_assert ! ( !self . 0 . access( cs) . freeq. is_full( ) ) ;
320
324
// SAFETY: freeq is not full.
321
325
unsafe {
@@ -358,8 +362,8 @@ impl<T, const N: usize> Sender<'_, T, N> {
358
362
}
359
363
}
360
364
361
- let slot = free_slot_ptr
362
- . replace ( None , cs)
365
+ // SAFETY: the value pointed to by ` free_slot_ptr` is still alive.
366
+ let slot = unsafe { free_slot_ptr . replace ( None , cs) }
363
367
. or_else ( || self . 0 . access ( cs) . freeq . pop_back ( ) ) ;
364
368
365
369
if let Some ( slot) = slot {
@@ -471,7 +475,9 @@ impl<T, const N: usize> Receiver<'_, T, N> {
471
475
472
476
// If someone is waiting in the WaiterQueue, wake the first one up & hand it the free slot.
473
477
if let Some ( ( wait_head, mut freeq_slot) ) = self . 0 . wait_queue . pop ( ) {
474
- freeq_slot. replace ( Some ( rs) , cs) ;
478
+ // SAFETY: the value pointed to by `freeq_slot` is still alive: we are in a critical
479
+ // section & the `SlotPtr` lives for at least the duration of the wait queue link.
480
+ unsafe { freeq_slot. replace ( Some ( rs) , cs) } ;
475
481
wait_head. wake ( ) ;
476
482
} else {
477
483
assert ! ( !self . 0 . access( cs) . freeq. is_full( ) ) ;
0 commit comments