Skip to content

Commit 968ceca

Browse files
committed
Make the GcErase trait an alias for GcRebrand
GcErase is now deprecated. Simplifies things significantly.
1 parent 347b6fc commit 968ceca

File tree

10 files changed

+38
-301
lines changed

10 files changed

+38
-301
lines changed

libs/context/src/handle.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use core::sync::atomic::{self, AtomicPtr, AtomicUsize, Ordering};
88
use alloc::boxed::Box;
99
use alloc::vec::Vec;
1010

11-
use zerogc::{Trace, GcSafe, GcErase, GcRebrand, GcVisitor, NullTrace, TraceImmutable, GcHandleSystem, GcBindHandle};
11+
use zerogc::{Trace, GcSafe, GcRebrand, GcVisitor, NullTrace, TraceImmutable, GcHandleSystem, GcBindHandle};
1212
use crate::{Gc, WeakCollectorRef, CollectorId, CollectorContext, CollectorRef, CollectionManager};
1313
use crate::collector::RawCollectorImpl;
1414

@@ -608,9 +608,9 @@ unsafe impl<T: GcSafe + Sync, C: RawHandleImpl + Sync> Sync for GcHandle<T, C> {
608608
unsafe impl<'gc, 'a, T, C> GcHandleSystem<'gc, 'a, T> for CollectorRef<C>
609609
where C: RawHandleImpl,
610610
T: GcSafe + 'gc,
611-
T: GcErase<'a, CollectorId<C>>,
612-
T::Erased: GcSafe + Sized {
613-
type Handle = GcHandle<T::Erased, C>;
611+
T: GcRebrand<'a, CollectorId<C>>,
612+
T::Branded: GcSafe + Sized {
613+
type Handle = GcHandle<T::Branded, C>;
614614

615615
#[inline]
616616
fn create_handle(gc: Gc<'gc, T, CollectorId<C>>) -> Self::Handle {

libs/derive/src/lib.rs

Lines changed: 1 addition & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -504,17 +504,11 @@ fn impl_derive_trace(input: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStre
504504
} else {
505505
impl_rebrand(input, info)?
506506
};
507-
let erase_impl = if info.config.nop_trace {
508-
impl_erase_nop(input, info)?
509-
} else {
510-
impl_erase(input, info)?
511-
};
512507
let gc_safe_impl = impl_gc_safe(input, info)?;
513508
let extra_impls = impl_extras(input, info)?;
514509
Ok(quote! {
515510
#trace_impl
516511
#rebrand_impl
517-
#erase_impl
518512
#gc_safe_impl
519513
#extra_impls
520514
})
@@ -665,172 +659,6 @@ fn impl_extras(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, E
665659
})
666660
}
667661

668-
669-
fn impl_erase_nop(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, Error> {
670-
let zerogc_crate = zerogc_crate();
671-
let name = &target.ident;
672-
let mut generics: Generics = target.generics.clone();
673-
for param in &mut generics.params {
674-
match param {
675-
GenericParam::Type(ref mut type_param) => {
676-
// Require all params are NullTrace
677-
type_param.bounds.push(parse_quote!(#zerogc_crate::NullTrace));
678-
},
679-
GenericParam::Lifetime(ref mut l) => {
680-
if l.lifetime == info.config.gc_lifetime() {
681-
assert!(!info.config.ignored_lifetimes.contains(&l.lifetime));
682-
return Err(Error::new(
683-
l.lifetime.span(),
684-
"Unexpected GC lifetime: Expected #[zerogc(nop_trace)] during #[derive(GcErase)]"
685-
))
686-
} else if info.config.ignored_lifetimes.contains(&l.lifetime) {
687-
// Explicitly ignored is okay, as long as it outlives the `'min`
688-
l.bounds.push(parse_quote!('min));
689-
} else {
690-
return Err(Error::new(
691-
l.span(),
692-
"Lifetime must be explicitly ignored"
693-
))
694-
}
695-
},
696-
GenericParam::Const(_) => {}
697-
}
698-
}
699-
let mut impl_generics = generics.clone();
700-
impl_generics.params.push(GenericParam::Lifetime(parse_quote!('min)));
701-
let collector_id = match info.config.collector_id {
702-
Some(ref id) => id.clone(),
703-
None => {
704-
impl_generics.params.push(GenericParam::Type(parse_quote!(Id: #zerogc_crate::CollectorId)));
705-
parse_quote!(Id)
706-
}
707-
};
708-
// Require that `Self: NullTrace`
709-
impl_generics.make_where_clause().predicates.push(WherePredicate::Type(PredicateType {
710-
lifetimes: None,
711-
bounded_ty: parse_quote!(Self),
712-
bounds: parse_quote!(#zerogc_crate::NullTrace),
713-
colon_token: Default::default()
714-
}));
715-
let (_, ty_generics, _) = generics.split_for_impl();
716-
let (impl_generics, _, where_clause) = impl_generics.split_for_impl();
717-
Ok(quote! {
718-
unsafe impl #impl_generics #zerogc_crate::GcErase<'min, #collector_id>
719-
for #name #ty_generics #where_clause {
720-
// We can pass-through because we are NullTrace
721-
type Erased = Self;
722-
}
723-
})
724-
}
725-
fn impl_erase(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, Error> {
726-
let zerogc_crate = zerogc_crate();
727-
let name = &target.ident;
728-
let mut generics: Generics = target.generics.clone();
729-
let mut rewritten_params = Vec::new();
730-
let mut rewritten_restrictions = Vec::new();
731-
let collector_id = match info.config.collector_id {
732-
Some(ref id) => id.clone(),
733-
None => parse_quote!(Id)
734-
};
735-
for param in &mut generics.params {
736-
let rewritten_param: GenericArgument;
737-
fn unsupported_lifetime_param(lt: &Lifetime) -> Error {
738-
Error::new(
739-
lt.span(),
740-
"Unless Self: NullTrace, derive(GcErase) is currently unable to handle lifetimes"
741-
)
742-
}
743-
match param {
744-
GenericParam::Type(ref mut type_param) => {
745-
let param_name = &type_param.ident;
746-
if info.is_ignored_param(&*type_param) {
747-
let param_name = &type_param.ident;
748-
rewritten_params.push(parse_quote!(#param_name));
749-
continue
750-
}
751-
fn rewrite_bound(bound: &TypeParamBound, info: &GcTypeInfo) -> Result<TypeParamBound, Error> {
752-
match bound {
753-
TypeParamBound::Trait(ref t) => Ok(TypeParamBound::Trait(t.clone())),
754-
TypeParamBound::Lifetime(ref lt) if *lt == info.config.gc_lifetime() => {
755-
Ok(parse_quote!('new_gc))
756-
},
757-
TypeParamBound::Lifetime(ref lt) => {
758-
Err(unsupported_lifetime_param(lt))
759-
}
760-
}
761-
}
762-
let original_bounds = type_param.bounds.iter()
763-
.map(|bound| rewrite_bound(bound, info))
764-
.collect::<Result<Vec<_>, _>>()?;
765-
type_param.bounds.push(parse_quote!(#zerogc_crate::GcErase<'min, #collector_id>));
766-
type_param.bounds.push(parse_quote!('min));
767-
let rewritten_type: Type = parse_quote!(<#param_name as #zerogc_crate::GcErase<'min, #collector_id>>::Erased);
768-
rewritten_restrictions.push(WherePredicate::Type(PredicateType {
769-
lifetimes: None,
770-
bounded_ty: rewritten_type.clone(),
771-
colon_token: Default::default(),
772-
bounds: original_bounds.into_iter().collect()
773-
}));
774-
rewritten_param = GenericArgument::Type(rewritten_type);
775-
},
776-
GenericParam::Lifetime(ref l) => {
777-
if l.lifetime == info.config.gc_lifetime() {
778-
rewritten_param = parse_quote!('min);
779-
assert!(!info.config.ignored_lifetimes.contains(&l.lifetime));
780-
} else {
781-
return Err(unsupported_lifetime_param(&l.lifetime))
782-
}
783-
},
784-
GenericParam::Const(ref param) => {
785-
let name = &param.ident;
786-
rewritten_param = GenericArgument::Const(parse_quote!(#name));
787-
}
788-
}
789-
rewritten_params.push(rewritten_param);
790-
}
791-
let mut field_types = Vec::new();
792-
match target.data {
793-
Data::Struct(ref s) => {
794-
for f in &s.fields {
795-
field_types.push(f.ty.clone());
796-
}
797-
},
798-
Data::Enum(ref e) => {
799-
for variant in &e.variants {
800-
for f in &variant.fields {
801-
field_types.push(f.ty.clone());
802-
}
803-
}
804-
},
805-
Data::Union(_) => {
806-
return Err(Error::new(target.ident.span(), "Unable to derive(GcErase) for unions"))
807-
}
808-
}
809-
let mut impl_generics = generics.clone();
810-
impl_generics.params.push(GenericParam::Lifetime(parse_quote!('min)));
811-
if info.config.collector_id.is_none() {
812-
impl_generics.params.push(GenericParam::Type(parse_quote!(Id: #zerogc_crate::CollectorId)));
813-
}
814-
impl_generics.make_where_clause().predicates.extend(rewritten_restrictions);
815-
let (_, ty_generics, _) = generics.split_for_impl();
816-
let (impl_generics, _, where_clause) = impl_generics.split_for_impl();
817-
let assert_erase = field_types.iter().map(|field_type| {
818-
let span = field_type.span();
819-
quote_spanned!(span => <#field_type as #zerogc_crate::GcErase<'min, #collector_id>>::assert_erase();)
820-
}).collect::<Vec<_>>();
821-
Ok(quote! {
822-
unsafe impl #impl_generics #zerogc_crate::GcErase<'min, #collector_id>
823-
for #name #ty_generics #where_clause {
824-
type Erased = #name::<#(#rewritten_params),*>;
825-
826-
fn assert_erase() {
827-
#(#assert_erase)*
828-
}
829-
}
830-
})
831-
}
832-
833-
834662
fn impl_rebrand_nop(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, Error> {
835663
let zerogc_crate = zerogc_crate();
836664
let name = &target.ident;
@@ -966,7 +794,7 @@ fn impl_rebrand(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
966794
}
967795
},
968796
Data::Union(_) => {
969-
return Err(Error::new(target.ident.span(), "Unable to derive(GcErase) for unions"))
797+
return Err(Error::new(target.ident.span(), "Unable to derive(GcRebrand) for unions"))
970798
}
971799
}
972800
let mut impl_generics = generics.clone();

libs/derive/src/macros.rs

Lines changed: 19 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ pub struct MacroInput {
5454
/// The associated type implemented as `GcRebrand::Branded`
5555
#[kwarg(optional)]
5656
branded_type: Option<Type>,
57-
/// The associated type implemented as `GcErase::Erased`
58-
#[kwarg(optional)]
59-
erased_type: Option<Type>,
6057
/// A (constant) expression determining whether the array needs to be traced
6158
#[kwarg(rename = "NEEDS_TRACE")]
6259
needs_trace: Expr,
@@ -164,15 +161,13 @@ impl MacroInput {
164161
} else {
165162
quote!()
166163
};
167-
let rebrand_impl = self.expand_brand_impl(true)?;
168-
let erase_impl = self.expand_brand_impl(false)?;
164+
let rebrand_impl = self.expand_rebrand_impl()?;
169165
Ok(quote! {
170166
#trace_impl
171167
#trace_immutable_impl
172168
#null_trace_impl
173169
#gcsafe_impl
174170
#rebrand_impl
175-
#erase_impl
176171
})
177172
}
178173
fn expand_trace_impl(&self, mutable: bool) -> Result<Option<TokenStream>, Error> {
@@ -263,9 +258,9 @@ impl MacroInput {
263258
unsafe impl #impl_generics #zerogc_crate::GcSafe for #target_type #where_clause {}
264259
})
265260
}
266-
fn expand_brand_impl(&self, rebrand: bool /* true => rebrand, false => erase */) -> Result<Option<TokenStream>, Error> {
261+
fn expand_rebrand_impl(&self) -> Result<Option<TokenStream>, Error> {
267262
let zerogc_crate = zerogc_crate();
268-
let requirements = if rebrand { self.bounds.rebrand.clone() } else { self.bounds.erase.clone() };
263+
let requirements = self.bounds.rebrand.as_ref();
269264
let target_type = &self.target_type;
270265
let mut generics = self.basic_generics();
271266
let id_type: Type = match self.collector_id {
@@ -290,11 +285,7 @@ impl MacroInput {
290285
return Ok(None); // They are requesting we dont implement it at all
291286
},
292287
None => {
293-
(true, if rebrand {
294-
vec![parse_quote!(#zerogc_crate::GcRebrand<'new_gc, #id_type>)]
295-
} else {
296-
vec![parse_quote!(#zerogc_crate::GcErase<'min, #id_type>)]
297-
})
288+
(true, vec![parse_quote!(#zerogc_crate::GcRebrand<'new_gc, #id_type>)])
298289
}
299290
};
300291
// generate default bounds
@@ -311,15 +302,9 @@ impl MacroInput {
311302
generics.make_where_clause()
312303
.predicates.push(WherePredicate::Type(PredicateType {
313304
lifetimes: None,
314-
bounded_ty: if rebrand {
315-
self.branded_type.clone().unwrap_or_else(|| {
316-
parse_quote!(<#type_name as #zerogc_crate::GcRebrand<'new_gc, Id>>::Branded)
317-
})
318-
} else {
319-
self.erased_type.clone().unwrap_or_else(|| {
320-
parse_quote!(<#type_name as #zerogc_crate::GcErase<'min, Id>>::Erased)
321-
})
322-
},
305+
bounded_ty: self.branded_type.clone().unwrap_or_else(|| {
306+
parse_quote!(<#type_name as #zerogc_crate::GcRebrand<'new_gc, Id>>::Branded)
307+
}),
323308
colon_token: Default::default(),
324309
bounds: bounds.clone(),
325310
}));
@@ -346,25 +331,13 @@ impl MacroInput {
346331
if let GenericParam::Type(ref tp) = param {
347332
let param_name = &tp.ident;
348333
generics.make_where_clause().predicates
349-
.push(if rebrand {
350-
parse_quote!(<#param_name as #zerogc_crate::GcRebrand<'new_gc, Id>>::Branded: Sized)
351-
} else {
352-
parse_quote!(<#param_name as #zerogc_crate::GcErase<'min, Id>>::Erased: Sized)
353-
})
334+
.push(parse_quote!(<#param_name as #zerogc_crate::GcRebrand<'new_gc, Id>>::Branded: Sized))
354335
}
355336
}
356337
}
357-
if rebrand {
358-
generics.params.push(parse_quote!('new_gc));
359-
} else {
360-
generics.params.push(parse_quote!('min));
361-
}
338+
generics.params.push(parse_quote!('new_gc));
362339
let (impl_generics, _, where_clause) = generics.split_for_impl();
363-
let target_trait = if rebrand {
364-
quote!(#zerogc_crate::GcRebrand<'new_gc, #id_type>)
365-
} else {
366-
quote!(#zerogc_crate::GcErase<'min, #id_type>)
367-
};
340+
let target_trait = quote!(#zerogc_crate::GcRebrand<'new_gc, #id_type>);
368341
fn rewrite_brand_trait(
369342
target: &Type, trait_name: &str, target_params: &HashSet<Ident>,
370343
target_trait: TokenStream, associated_type: Ident
@@ -390,30 +363,17 @@ impl MacroInput {
390363
GenericParam::Type(ref tp) => Some(tp.ident.clone()),
391364
_ => None
392365
}).collect::<HashSet<_>>();
393-
let associated_type = if rebrand {
394-
let branded = self.branded_type.clone().map_or_else(|| {
395-
rewrite_brand_trait(
396-
&self.target_type, "GcRebrand",
397-
&target_params,
398-
parse_quote!(#zerogc_crate::GcRebrand<'new_gc, #id_type>),
399-
parse_quote!(Branded)
400-
)
401-
}, Ok)?;
402-
quote!(type Branded = #branded;)
403-
} else {
404-
let erased = Ok(self.erased_type.clone()).transpose().unwrap_or_else(|| {
405-
rewrite_brand_trait(
406-
&self.target_type, "GcErase",
407-
&target_params,
408-
parse_quote!(#zerogc_crate::GcErase<'min, #id_type>),
409-
parse_quote!(Erased)
410-
)
411-
})?;
412-
quote!(type Erased = #erased;)
413-
};
366+
let branded = self.branded_type.clone().map_or_else(|| {
367+
rewrite_brand_trait(
368+
&self.target_type, "GcRebrand",
369+
&target_params,
370+
parse_quote!(#zerogc_crate::GcRebrand<'new_gc, #id_type>),
371+
parse_quote!(Branded)
372+
)
373+
}, Ok)?;
414374
Ok(Some(quote! {
415375
unsafe impl #impl_generics #target_trait for #target_type #where_clause {
416-
#associated_type
376+
type Branded = #branded;
417377
}
418378
}))
419379
}
@@ -497,9 +457,6 @@ pub struct CustomBounds {
497457
/// The requirements to implement `GcRebrand`
498458
#[kwarg(optional, rename = "GcRebrand")]
499459
rebrand: Option<TraitRequirements>,
500-
/// The requirements to implement `GcErase`
501-
#[kwarg(optional, rename = "GcErase")]
502-
erase: Option<TraitRequirements>,
503460
#[kwarg(optional)]
504461
visit_inside_gc: Option<Syn<WhereClause>>
505462
}

src/cell.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use core::cell::Cell;
1717

1818
use zerogc_derive::unsafe_gc_impl;
1919

20-
use crate::{Trace, NullTrace, GcDirectBarrier, CollectorId, GcErase, GcRebrand, GcSafe};
20+
use crate::{Trace, NullTrace, GcDirectBarrier, CollectorId, GcRebrand, GcSafe};
2121

2222
/// A `Cell` pointing to a garbage collected object.
2323
///
@@ -85,10 +85,8 @@ unsafe_gc_impl!(
8585
Trace => { where T: Trace + Copy },
8686
// NOTE: TraceImmutable requires a 'NullTrace' for interior mutability
8787
TraceImmutable => { where T: NullTrace + Copy },
88-
GcErase => { where T: Trace + Copy + GcErase<'min, Id>, Id: CollectorId, T::Erased: Copy + Trace },
8988
GcRebrand => { where T: Trace + Copy + GcRebrand<'new_gc, Id>, Id: CollectorId,T::Branded: Copy + Trace }
9089
},
91-
erased_type => GcCell<T::Erased>,
9290
branded_type => GcCell<T::Branded>,
9391
null_trace => { where T: GcSafe + Copy + NullTrace },
9492
trace_mut => |self, visitor| {

0 commit comments

Comments
 (0)