// This is unsafe, since we must externally guarantee that no-one still holds a pointer to the data
// (Luckily this is the point of the garbage collector!)
This is unsafe, since we must externally guarantee that no-one still holds a pointer to the data
(Luckily this is the point of the garbage collector!)
This is unsafe since we must externally guarantee that no - one still holds a pointer to the data ( Luckily this is the point of the garbage collector! )
pub unsafe fn deallocate(self) {
        let scan_ptr: *const dyn Scan = self.scan_ptr;
        match self.deallocation_action {
            DeallocationAction::DoNothing => {
                // The name here is a bit of a lie, because we still need to invalidate handles
                let mut scanner = Scanner::new(|h| {
                    h.invalidate();
                });
                (&*scan_ptr).scan(&mut scanner);
            }
            DeallocationAction::RunDrop => {
                // Safe type shift: the contract of this method is that the scan_ptr doesn't alias
                // + ManuallyDrop is repr(transparent)
                let droppable_ptr = scan_ptr as *mut ManuallyDrop<dyn Scan>;
                let droppable_ref = &mut *droppable_ptr;
                ManuallyDrop::drop(droppable_ref);
            }
            DeallocationAction::RunFinalizer { finalize_ptr } => {
                // First of all invalidate handles, just in case of a bad `Finalize` implementation
                // (If it doesn't delegate correctly, `Gc`s could be left dangling)
                {
                    let mut scanner = Scanner::new(|h| {
                        h.invalidate();
                    });
                    (&*scan_ptr).scan(&mut scanner);
                }
                // We know this method can only be called if `scan_ptr` doesn't alias
                // And we know `finalize_ptr` ~= `scan_ptr`
                // So we can run `finalize` here, right before deallocation
                (&mut *(finalize_ptr as *mut dyn Finalize)).finalize();
            }
        }
        let dealloc_layout = Layout::for_value(&*scan_ptr);
        let heap_ptr = scan_ptr as *mut u8;
        dealloc(heap_ptr, dealloc_layout);
    }
pub unsafe fn deallocate ( self ) { let scan_ptr : * const dyn Scan = self . scan_ptr ; match self . deallocation_action { DeallocationAction :: DoNothing => { // The name here is a bit of a lie, because we still need to invalidate handles let mut scanner = Scanner :: new ( | h | { h . invalidate ( ) ; } ) ; ( & * scan_ptr ) . scan ( & mut scanner ) ; } DeallocationAction :: RunDrop => { // Safe type shift: the contract of this method is that the scan_ptr doesn't alias // + ManuallyDrop is repr(transparent) let droppable_ptr = scan_ptr as * mut ManuallyDrop < dyn Scan > ; let droppable_ref = & mut * droppable_ptr ; ManuallyDrop :: drop ( droppable_ref ) ; } DeallocationAction :: RunFinalizer { finalize_ptr } => { // First of all invalidate handles, just in case of a bad `Finalize` implementation // (If it doesn't delegate correctly, `Gc`s could be left dangling) { let mut scanner = Scanner :: new ( | h | { h . invalidate ( ) ; } ) ; ( & * scan_ptr ) . scan ( & mut scanner ) ; } // We know this method can only be called if `scan_ptr` doesn't alias // And we know `finalize_ptr` ~= `scan_ptr` // So we can run `finalize` here, right before deallocation ( & mut * ( finalize_ptr as * mut dyn Finalize ) ) . finalize ( ) ; } } let dealloc_layout = Layout :: for_value ( & * scan_ptr ) ; let heap_ptr = scan_ptr as * mut u8 ; dealloc ( heap_ptr , dealloc_layout ) ; }
This is unsafe, since we must externally guarantee that no-one still holds a pointer to the data
(Luckily this is the point of the garbage collector!)
This is unsafe since we must externally guarantee that no - one still holds a pointer to the data ( Luckily this is the point of the garbage collector! )
self