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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
use crate::;
pub use Collect;
/// A trait for garbage collected objects that can be placed into `Gc` pointers. This trait is
/// unsafe, because `Gc` pointers inside an Arena are assumed never to be dangling, and in order to
/// ensure this certain rules must be followed:
///
/// 1. `Collect::trace` *must* trace over *every* `Gc` and `GcWeak` pointer held inside this type.
/// 2. Held `Gc` and `GcWeak` pointers must not be accessed inside `Drop::drop` since during drop
/// any such pointer may be dangling.
/// 3. Internal mutability *must* not be used to adopt new `Gc` or `GcWeak` pointers without
/// calling appropriate write barrier operations during the same arena mutation.
///
/// It is, however, possible to implement this trait safely by procedurally deriving it (see
/// [`gc_arena_derive::Collect`]), which requires that every field in the structure also implement
/// `Collect`, and ensures that `Drop` cannot safely be implemented. Internally mutable types like
/// `Cell` and `RefCell` do not implement `Collect` in such a way that it is possible to store
/// `Gc` pointers inside them, so write barrier requirements cannot be broken when procedurally
/// deriving `Collect`. A safe way of providing internal mutability in this case is to use
/// [`crate::lock::Lock<T>`] and [`crate::lock::RefLock<T>`], which provides internal mutability
/// while ensuring that write barriers are correctly executed.
pub unsafe
/// The trait that is passed to the [`Collect::trace`] method.
///
/// Though [`Collect::trace`] is primarily used during the marking phase of the mark and sweep
/// collector, this is a trait rather than a concrete type to facilitate other kinds of uses.
///
/// This trait is not itself unsafe, but implementers of [`Collect`] *must* uphold the safety
/// guarantees of [`Collect`] when using this trait.
/// If a type is static, we know that it can never hold `Gc` pointers, so it is safe to provide a
/// simple empty `Collect` implementation.
///
/// This macro may be called in multiple ways:
///
/// ```ignore
/// static_collect!(MyTrait<'gc>);
/// static_collect!(<T> MyTrait<'gc, T> where T: Clone);
/// static_collect!(<T> MyTrait<'gc, Assoc = T>);
/// ```
///
/// Type parameters may be declared using `<A, B>` at the beginning of the macro, along with an
/// optional trailing where clause.
};
=>
}
/// An object safe version of the [`Collect`] trait.
///
/// This is automatically implemented for all types that implement the normal `Collect` trait.
///
/// The `dyn DynCollect` trait object implements `Collect` automatically, but trait objects for user
/// defined traits that have `DynCollect` as a parent trait can also be made to implement `Collect`
/// by using the [`dyn_collect`] macro.
pub unsafe
unsafe
unsafe
/// Implement [`Collect`] for custom trait objects.
///
/// The trait being implemented must have [`DynCollect`] as a supertrait.
///
/// This macro may be called in multiple ways:
///
/// ```ignore
/// dyn_collect!(MyTrait<'gc>);
/// dyn_collect!(<T> MyTrait<'gc, T> where T: Clone);
/// dyn_collect!(<T> MyTrait<'gc, Assoc = T>);
/// ```
///
/// The generated impl always has a single `'gc` lifetime parameter that is used as the `'gc`
/// parameter on the `Collect` trait. Additional type and lifetime parameters may be declared using
/// `<A, B>` at the beginning of the macro, along with an optional trailing where clause.
};
=>
}
pub use crate__dyn_collect as dyn_collect;