[][src]Trait shredder::Scan

pub unsafe trait Scan: GcSafe {
    fn scan(&self, scanner: &mut Scanner);
}

A trait capturing the ability of data to be scanned for references to data in a Gc.

This is unsafe, since a bad scan implementation can cause memory unsafety in two ways:

  1. If scan scans data that this object does not own
  2. If scan does anything other than scan data with a non-'static lifetime

The importance of (1) is so that the collector does not collect data that is in use. The importance of (2) is so that this data can still be scanned even after its lifetime has technically expired.

Regarding (1): Note that it's okay to miss data that you own. Missing connected data can only cause memory leaks--not memory unsafety. Regarding (2): In particular, scan should not call anything but Scan on R and RMut. Even implicitly using the deref implementations on these structs is incorrect.

Importantly, any empty scan implementation is safe (assuming the GcSafe impl is correct)

NB: It's important that scan only scans data that is truly owned. Rc/Arc cannot have sensible scan implementations, since each individual smart pointer doesn't own the underlying data.

Examples

In practice you probably want to use the derive macro:

use shredder::Scan;

#[derive(Scan)]
struct Example {
    v: u32
}

This also comes with a #[shredder(skip)] attribute, for when some data implements GcSafe but not Scan

use std::sync::Arc;
use shredder::Scan;

#[derive(Scan)]
struct Example {
    #[shredder(skip)]
    v: Arc<u32>
}

This can work for any Send data using GcSafeWrapper

use std::sync::Arc;
use shredder::{Scan, GcSafeWrapper};

struct SendDataButNotScan {
    i: u32
}

#[derive(Scan)]
struct Example {
    #[shredder(skip)]
    v: GcSafeWrapper<SendDataButNotScan>
}

In emergencies, you can break out #[shredder(unsafe_skip)], but this is potentially unsafe

use std::sync::Arc;
use shredder::{Scan, GcSafeWrapper};

struct NotEvenSendData {
    data: *mut u32
}

#[derive(Scan)]
struct Example {
    #[shredder(unsafe_skip)]
    v: NotEvenSendData
}

Required methods

fn scan(&self, scanner: &mut Scanner)

scan should use the scanner to scan all of its directly owned data

Loading content...

Implementations on Foreign Types

impl<T> Scan for &'static T[src]

impl<T> Scan for &'static mut T[src]

impl<T: Scan> Scan for Vec<T>[src]

impl<T: Scan, S: BuildHasher> Scan for HashSet<T, S>[src]

impl<K: Scan, V: Scan, S: BuildHasher> Scan for HashMap<K, V, S>[src]

impl<T: Scan> Scan for RefCell<T>[src]

impl<T: Scan> Scan for Option<T>[src]

impl<T: Scan> Scan for Mutex<T>[src]

impl<T: Scan> Scan for RwLock<T>[src]

impl Scan for isize[src]

impl Scan for usize[src]

impl Scan for i8[src]

impl Scan for u8[src]

impl Scan for i16[src]

impl Scan for u16[src]

impl Scan for i32[src]

impl Scan for u32[src]

impl Scan for i64[src]

impl Scan for u64[src]

impl Scan for i128[src]

impl Scan for u128[src]

impl Scan for String[src]

impl Scan for Duration[src]

impl Scan for Instant[src]

Loading content...

Implementors

impl<'a, T: ?Sized> Scan for R<'a, T>[src]

impl<'a, T: ?Sized> Scan for RMut<'a, T>[src]

impl<T: Scan> Scan for Gc<T>[src]

Loading content...