Skip to content

Commit cedb3d1

Browse files
committed
Use const generics for arrays.
Now Trace is implemented for arrays of arbitrary size :) Modify unsafe_gc_impl! to support const-generic parameters.
1 parent 87e7fb9 commit cedb3d1

File tree

3 files changed

+41
-23
lines changed

3 files changed

+41
-23
lines changed

libs/derive/src/lib.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,30 @@ pub(crate) fn zerogc_crate() -> TokenStream {
3737
quote!(::zerogc)
3838
}
3939

40+
/// Sort the parameters so that lifetime parameters come before
41+
/// type parameters, and type parameters come before const paramaters
42+
pub(crate) fn sort_params(generics: &mut Generics) {
43+
#[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Debug)]
44+
enum ParamOrder {
45+
Lifetime,
46+
Type,
47+
Const,
48+
EndPunct
49+
}
50+
let mut pairs = std::mem::take(&mut generics.params).into_pairs()
51+
.collect::<Vec<_>>();
52+
use syn::punctuated::Pair;
53+
pairs.sort_by_key(|pair| {
54+
match pair {
55+
Pair::Punctuated(syn::GenericParam::Lifetime(_), _) => ParamOrder::Lifetime,
56+
Pair::Punctuated(syn::GenericParam::Type(_), _) => ParamOrder::Type,
57+
Pair::Punctuated(syn::GenericParam::Const(_), _) => ParamOrder::Const,
58+
Pair::End(_) => ParamOrder::EndPunct,
59+
}
60+
});
61+
generics.params = pairs.into_iter().collect();
62+
}
63+
4064
pub(crate) fn emit_warning(msg: impl ToString, span: Span) {
4165
let mut d = proc_macro::Diagnostic::new(proc_macro::Level::Warning, msg.to_string());
4266
d.set_spans(span.unwrap());

libs/derive/src/macros.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ impl MacroInput {
320320
Some(clause) => clause.predicates,
321321
None => return Ok(None)
322322
});
323+
crate::sort_params(&mut generics);
323324
let (impl_generics, _, where_clause) = generics.split_for_impl();
324325
Ok(Some(quote! {
325326
unsafe impl #impl_generics #zerogc_crate::GcSafe<#gc_lt, #id_type> for #target_type #where_clause {}
@@ -344,6 +345,7 @@ impl MacroInput {
344345
None => return Ok(None)
345346
}
346347
);
348+
crate::sort_params(&mut generics);
347349
let deserialize = match *strategy {
348350
DeserializeStrategy::Delegate(_span) => {
349351
// NOTE: quote_spanned messes up hygiene
@@ -518,6 +520,7 @@ impl MacroInput {
518520
}
519521
}
520522
generics.params.push(parse_quote!('new_gc));
523+
crate::sort_params(&mut generics);
521524
let (impl_generics, _, where_clause) = generics.split_for_impl();
522525
let target_trait = quote!(#zerogc_crate::GcRebrand<'new_gc, #id_type>);
523526
fn rewrite_brand_trait(

src/manually_traced/core.rs

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -199,29 +199,20 @@ unsafe_gc_impl! {
199199

200200
trace_tuple! { A, B, C, D, E, F, G, H, I }
201201

202-
macro_rules! trace_array {
203-
($size:tt) => {
204-
unsafe_gc_impl! {
205-
target => [T; $size],
206-
params => [T],
207-
null_trace => { where T: NullTrace },
208-
bounds => {
209-
GcRebrand => { where T: GcRebrand<'new_gc, Id>, T::Branded: Sized },
210-
},
211-
NEEDS_TRACE => T::NEEDS_TRACE,
212-
NEEDS_DROP => T::NEEDS_DROP,
213-
branded_type => [<T as GcRebrand<'new_gc, Id>>::Branded; $size],
214-
collector_id => *,
215-
trace_template => |self, visitor| {
216-
visitor.#trace_func(#b*self as #b [T])
217-
},
218-
}
219-
};
220-
{ $($size:tt),* } => ($(trace_array!($size);)*)
221-
}
222-
trace_array! {
223-
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
224-
24, 32, 48, 64, 100, 128, 256, 512, 1024, 2048, 4096
202+
unsafe_gc_impl! {
203+
target => [T; SIZE],
204+
params => [T, const SIZE: usize],
205+
null_trace => { where T: NullTrace },
206+
bounds => {
207+
GcRebrand => { where T: GcRebrand<'new_gc, Id>, T::Branded: Sized },
208+
},
209+
NEEDS_TRACE => T::NEEDS_TRACE,
210+
NEEDS_DROP => T::NEEDS_DROP,
211+
branded_type => [<T as GcRebrand<'new_gc, Id>>::Branded; SIZE],
212+
collector_id => *,
213+
trace_template => |self, visitor| {
214+
visitor.#trace_func(#b*self as #b [T])
215+
},
225216
}
226217

227218
/*

0 commit comments

Comments
 (0)