1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use crate::prelude::*;
use std::collections::{HashMap, HashSet};
use crate::CollectorId;
unsafe_immutable_trace_iterable!(HashMap<K, V>; element = { (&K, &V) });
unsafe impl<K: TraceImmutable, V: Trace> Trace for HashMap<K, V> {
const NEEDS_TRACE: bool = K::NEEDS_TRACE || V::NEEDS_TRACE;
fn visit<Visit: GcVisitor>(&mut self, visitor: &mut Visit) -> Result<(), Visit::Err> {
if !Self::NEEDS_TRACE { return Ok(()); };
for (key, value) in self.iter_mut() {
visitor.visit_immutable(key)?;
visitor.visit(value)?;
}
Ok(())
}
}
unsafe impl<K: GcSafe + TraceImmutable, V: GcSafe> GcSafe for HashMap<K, V> {
const NEEDS_DROP: bool = true;
}
unsafe impl<'new_gc, Id, K, V> GcRebrand<'new_gc, Id> for HashMap<K, V>
where Id: CollectorId, K: TraceImmutable + GcRebrand<'new_gc, Id>,
V: GcRebrand<'new_gc, Id>,
<K as GcRebrand<'new_gc, Id>>::Branded: TraceImmutable + Sized,
<V as GcRebrand<'new_gc, Id>>::Branded: Sized {
type Branded = HashMap<
<K as GcRebrand<'new_gc, Id>>::Branded,
<V as GcRebrand<'new_gc, Id>>::Branded
>;
}
unsafe impl<'a, Id, K, V> GcErase<'a, Id> for HashMap<K, V>
where Id: CollectorId, K: TraceImmutable + GcErase<'a, Id>,
V: GcErase<'a, Id>,
<K as GcErase<'a, Id>>::Erased: TraceImmutable + Sized,
<V as GcErase<'a, Id>>::Erased: Sized {
type Erased = HashMap<
<K as GcErase<'a, Id>>::Erased,
<V as GcErase<'a, Id>>::Erased
>;
}
unsafe_immutable_trace_iterable!(HashSet<V>; element = { &V });
unsafe impl<V: TraceImmutable> Trace for HashSet<V> {
const NEEDS_TRACE: bool = V::NEEDS_TRACE;
fn visit<Visit: GcVisitor>(&mut self, visitor: &mut Visit) -> Result<(), Visit::Err> {
if !Self::NEEDS_TRACE { return Ok(()); };
for value in self.iter() {
visitor.visit_immutable(value)?;
}
Ok(())
}
}
unsafe_gc_brand!(HashSet, immut = required; V);