Skip to content

Commit b4f9baf

Browse files
committed
Implement Trace/GcBrand for **all** tuple sizes
Before the macors weren't recursing properly, so we only implemented it for 9-argument tuples ^_^ Add a test to verify that varius `core` types actually implement `Trace` properly. Unfortunately, the tests don't compile :(
1 parent f3fc420 commit b4f9baf

File tree

2 files changed

+42
-12
lines changed

2 files changed

+42
-12
lines changed

src/manually_traced/core.rs

+40-9
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,29 @@
77
use core::num::Wrapping;
88

99
use crate::prelude::*;
10-
use crate::{GcDirectBarrier, CollectorId};
10+
use crate::GcDirectBarrier;
1111

1212
use zerogc_derive::unsafe_gc_impl;
1313

14-
macro_rules! __rec_trace_tuple {
15-
($($param:ident),*) => {
16-
// Nothing remaining
14+
macro_rules! trace_tuple {
15+
{ $single_param:ident } => {
16+
trace_tuple_impl!($single_param);
1717
};
18-
($first_param:ident, $($param:ident),+) => {
19-
trace_tuple!($($param),*);
18+
{ $first_param:ident, $($param:ident),* } => {
19+
trace_tuple! { $($param),* }
20+
trace_tuple_impl!( $first_param, $($param),*);
2021
};
2122
}
22-
macro_rules! trace_tuple {
23-
{ $($param:ident),* } => {
24-
__rec_trace_tuple!($($param),* );
23+
24+
macro_rules! trace_tuple_impl {
25+
{ $($param:ident),* } => {
2526
unsafe_gc_impl! {
2627
target => ( $($param,)* ),
2728
params => [$($param),*],
29+
bounds => {
30+
GcRebrand => { where $($param: GcRebrand<'new_gc, Id>),* },
31+
GcErase => { where $($param: GcErase<'min, Id>),* },
32+
}
2833
null_trace => { where $($param: NullTrace,)* i32: Sized },
2934
/*
3035
* HACK: Macros don't allow using `||` as separator,
@@ -276,4 +281,30 @@ unsafe_gc_impl! {
276281
// We can trace `Wrapping` by simply tracing its interior
277282
visitor.#visit_func(#b self.0)
278283
}
284+
}
285+
286+
#[cfg(test)]
287+
mod test {
288+
use crate::dummy_impl::Gc;
289+
use zerogc_derive::Trace;
290+
use crate::prelude::*;
291+
#[test]
292+
fn test_null_trace() {
293+
assert!(!<Option<i32> as Trace>::NEEDS_TRACE);
294+
assert!(!<Option<(i32, char)> as Trace>::NEEDS_TRACE)
295+
}
296+
#[derive(Trace)]
297+
struct Rec<'gc> {
298+
inner: Gc<'gc, Rec<'gc>>,
299+
inner_tuple: (Gc<'gc, Rec<'gc>>, Gc<'gc, Option<i32>>),
300+
inner_opt: Option<Gc<'gc, Rec<'gc>>>,
301+
inner_opt_tuple: Option<(Gc<'gc, Rec<'gc>>, Gc<'gc, char>)>,
302+
}
303+
#[test]
304+
fn test_trace<'gc>() {
305+
assert!(<Option<Gc<'gc, i32>> as Trace>::NEEDS_TRACE);
306+
assert!(<Option<(Gc<'gc, i32>, char)> as Trace>::NEEDS_TRACE);
307+
assert!(<Rec<'gc> as Trace>::NEEDS_TRACE);
308+
assert!(<Gc<'gc, Rec<'gc>> as Trace>::NEEDS_TRACE);
309+
}
279310
}

src/manually_traced/stdlib.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
//! Types that are in `libcore` and are `#![no_std]` should go in the core module,
44
//! but anything that requires the rest of the stdlib (including collections and allocations),
55
//! should go in this module.
6-
use crate::prelude::*;
7-
86
use std::collections::{HashMap, HashSet};
9-
use crate::CollectorId;
107

118
use zerogc_derive::unsafe_gc_impl;
129

10+
use crate::prelude::*;
11+
1312

1413
unsafe_gc_impl! {
1514
target => HashMap<K, V>,

0 commit comments

Comments
 (0)