1pub unsafe trait RcuDroppable: Send + 'static {}
11
12macro_rules! impl_rcu_droppable {
13 ($($t:ty),* $(,)?) => {
14 $(
15 unsafe impl RcuDroppable for $t {}
18 )*
19 };
20}
21
22impl_rcu_droppable!(
23 (),
24 bool,
25 char,
26 u8,
27 u16,
28 u32,
29 u64,
30 u128,
31 usize,
32 i8,
33 i16,
34 i32,
35 i64,
36 i128,
37 isize,
38 f32,
39 f64,
40 String,
41 str,
42 bstr::BString,
43 bstr::BStr,
44 fuchsia_runtime::UtcTimeline,
45 fuchsia_trace::Id,
46 shared_buffer::SharedBuffer,
47 std::collections::hash_map::RandomState,
48 std::num::NonZeroU8,
49 std::num::NonZeroU16,
50 std::num::NonZeroU32,
51 std::num::NonZeroU64,
52 std::num::NonZeroU128,
53 std::num::NonZeroUsize,
54 std::num::NonZeroI8,
55 std::num::NonZeroI16,
56 std::num::NonZeroI32,
57 std::num::NonZeroI64,
58 std::num::NonZeroI128,
59 std::num::NonZeroIsize,
60 std::sync::atomic::AtomicBool,
61 std::sync::atomic::AtomicI8,
62 std::sync::atomic::AtomicI16,
63 std::sync::atomic::AtomicI32,
64 std::sync::atomic::AtomicI64,
65 std::sync::atomic::AtomicIsize,
66 std::sync::atomic::AtomicU8,
67 std::sync::atomic::AtomicU16,
68 std::sync::atomic::AtomicU32,
69 std::sync::atomic::AtomicU64,
70 std::sync::atomic::AtomicUsize,
71 std::ops::RangeFull,
72 std::time::Duration,
73 std::time::Instant,
74 zx::BootTimeline,
75 zx::Koid,
76 zx::MonotonicTimeline,
77 zx::Rights,
78 zx::Vmo,
79);
80
81unsafe impl<T: ?Sized + Sync + 'static> RcuDroppable for &'static T {}
83unsafe impl<H: 'static> RcuDroppable for std::hash::BuildHasherDefault<H> {}
85unsafe impl<T: ?Sized + Send + 'static> RcuDroppable for std::marker::PhantomData<T> {}
87unsafe impl<T: RcuDroppable> RcuDroppable for Option<T> {}
89unsafe impl<T: RcuDroppable, E: RcuDroppable> RcuDroppable for Result<T, E> {}
91unsafe impl<T: ?Sized + RcuDroppable> RcuDroppable for Box<T> {}
93unsafe impl<T: ?Sized + RcuDroppable + Sync> RcuDroppable for std::sync::Arc<T> {}
95unsafe impl<T: RcuDroppable + Sync> RcuDroppable for std::sync::OnceLock<T> {}
97unsafe impl<T: ?Sized + Send + Sync + 'static> RcuDroppable for std::sync::Weak<T> {}
99unsafe impl<T: RcuDroppable> RcuDroppable for Vec<T> {}
101unsafe impl<T: RcuDroppable, const N: usize> RcuDroppable for [T; N] {}
103unsafe impl<T: RcuDroppable> RcuDroppable for [T] {}
105unsafe impl<T: Send + 'static> RcuDroppable for std::sync::mpsc::Sender<T> {}
107unsafe impl<T: Send + 'static> RcuDroppable for std::sync::mpsc::SyncSender<T> {}
109unsafe impl<T: Send + 'static> RcuDroppable for futures::channel::mpsc::Sender<T> {}
111unsafe impl<T: Send + 'static> RcuDroppable for futures::channel::mpsc::UnboundedSender<T> {}
113unsafe impl<T: Send + 'static> RcuDroppable for futures::channel::oneshot::Sender<T> {}
115unsafe impl<T: 'static> RcuDroppable for std::sync::atomic::AtomicPtr<T> {}
117unsafe impl<T: 'static> RcuDroppable for crate::rcu_ptr::RcuPtr<T> {}
119
120unsafe impl<T: RcuDroppable> RcuDroppable for std::ops::Range<T> {}
123unsafe impl<T: RcuDroppable> RcuDroppable for std::ops::RangeFrom<T> {}
125unsafe impl<T: RcuDroppable> RcuDroppable for std::ops::RangeInclusive<T> {}
127unsafe impl<T: RcuDroppable> RcuDroppable for std::ops::RangeTo<T> {}
129unsafe impl<T: RcuDroppable> RcuDroppable for std::ops::RangeToInclusive<T> {}
131
132unsafe impl<T: RcuDroppable + Sync> RcuDroppable for crate::RcuDroppableArc<T> {}
135unsafe impl<T: RcuDroppable + Sync> RcuDroppable for crate::RcuBox<T> {}
137unsafe impl<T: RcuDroppable + Sync> RcuDroppable for crate::RcuOptionArc<T> {}
139unsafe impl<T: RcuDroppable + Sync> RcuDroppable for crate::RcuOptionBox<T> {}
141unsafe impl<T: Send + Sync + 'static> RcuDroppable for crate::RcuWeak<T> {}
143unsafe impl<T: RcuDroppable + Sync> RcuDroppable for crate::RcuArc<T> {}
145unsafe impl<T: ?Sized + RcuDroppable> RcuDroppable for fuchsia_sync::Mutex<T> {}
148unsafe impl<T: ?Sized + RcuDroppable> RcuDroppable for fuchsia_sync::RwLock<T> {}
150
151unsafe impl<T: Send + 'static, U: Send + 'static> RcuDroppable for zx::Clock<T, U> {}
155
156unsafe impl<A: RcuDroppable> RcuDroppable for (A,) {}
159unsafe impl<A: RcuDroppable, B: RcuDroppable> RcuDroppable for (A, B) {}
161unsafe impl<A: RcuDroppable, B: RcuDroppable, C: RcuDroppable> RcuDroppable for (A, B, C) {}
163unsafe impl<A: RcuDroppable, B: RcuDroppable, C: RcuDroppable, D: RcuDroppable> RcuDroppable
165 for (A, B, C, D)
166{
167}
168
169#[expect(dead_code)]
172#[cfg(test)]
173mod tests {
174 use crate::RcuDroppable;
175
176 #[derive(RcuDroppable)]
177 struct UnitStruct;
178
179 #[derive(RcuDroppable)]
180 struct TupleStruct(u32, String);
181
182 #[derive(RcuDroppable)]
183 struct NamedStruct<T> {
184 foo: T,
185 bar: Vec<u8>,
186 }
187
188 #[derive(RcuDroppable)]
189 enum TestEnum<T> {
190 A(T),
191 B { val: String },
192 C,
193 }
194
195 #[derive(RcuDroppable)]
196 struct ComplexStruct {
197 atomic: std::sync::atomic::AtomicUsize,
198 range: std::ops::Range<usize>,
199 non_zero: std::num::NonZeroU32,
200 mutex: fuchsia_sync::Mutex<u32>,
201 rwlock: fuchsia_sync::RwLock<String>,
202 rcu_arc: crate::RcuArc<u32>,
203 weak: std::sync::Weak<u32>,
204 }
205
206 fn assert_rcu_droppable<T: super::RcuDroppable>() {}
207
208 #[test]
209 fn test_derive_rcu_droppable() {
210 assert_rcu_droppable::<UnitStruct>();
211 assert_rcu_droppable::<TupleStruct>();
212 assert_rcu_droppable::<NamedStruct<u32>>();
213 assert_rcu_droppable::<TestEnum<u64>>();
214 assert_rcu_droppable::<ComplexStruct>();
215 assert_rcu_droppable::<bstr::BString>();
216 assert_rcu_droppable::<futures::channel::mpsc::UnboundedSender<u32>>();
217 }
218}