@@ -15,6 +15,24 @@ use std::io::Write;
1515
1616mod macros;
1717
18+ /// Magic const that expands to either `::zerogc` or `crate::`
19+ /// depending on whether we are currently bootstraping (compiling `zerogc` itself)
20+ ///
21+ /// This is equivalant to `$crate` for regular macros
22+ pub ( crate ) fn zerogc_crate ( ) -> TokenStream {
23+ if is_bootstraping ( ) {
24+ quote ! ( crate )
25+ } else {
26+ quote ! ( :: zerogc)
27+ }
28+ }
29+
30+ /// If we are currently compiling the base crate `zerogc` itself
31+ pub ( crate ) fn is_bootstraping ( ) -> bool {
32+ :: proc_macro:: tracked_env:: var ( "CARGO_CRATE_NAME" )
33+ . expect ( "Expected `CARGO_CRATE_NAME`" ) == "zerogc"
34+ }
35+
1836struct MutableFieldOpts {
1937 public : bool
2038}
@@ -410,14 +428,15 @@ fn impl_derive_trace(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
410428}
411429
412430fn trace_fields ( fields : & Fields , access_ref : & mut dyn FnMut ( Member ) -> TokenStream ) -> TokenStream {
431+ let zerogc_crate = zerogc_crate ( ) ;
413432 // TODO: Detect if we're a unit struct and implement `NullTrace`
414433 let mut result = Vec :: new ( ) ;
415434 for ( index, field) in fields. iter ( ) . enumerate ( ) {
416435 let val = access_ref ( match field. ident {
417436 Some ( ref ident) => Member :: Named ( ident. clone ( ) ) ,
418437 None => Member :: Unnamed ( Index :: from ( index) )
419438 } ) ;
420- result. push ( quote ! ( :: zerogc :: Trace :: visit( #val, & mut * visitor) ?) ) ;
439+ result. push ( quote ! ( #zerogc_crate :: Trace :: visit( #val, & mut * visitor) ?) ) ;
421440 }
422441 quote ! ( #( #result; ) * )
423442}
@@ -482,13 +501,13 @@ fn impl_extras(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, E
482501 ) )
483502 } ;
484503 // NOTE: Specially quoted since we want to blame the field for errors
485- let field_as_ptr = quote_spanned ! ( field. span( ) => GcCell :: as_ptr( & ( * self . value( ) ) . #original_name) ) ;
486- let barrier = quote_spanned ! ( field. span( ) => :: zerogc :: GcDirectBarrier :: write_barrier( & value, & self , offset) ) ;
504+ let field_as_ptr = quote_spanned ! ( field. span( ) => ZEROGC_CRATE :: GcCell :: as_ptr( & ( * self . value( ) ) . #original_name) ) ;
505+ let barrier = quote_spanned ! ( field. span( ) => ZEROGC_CRATE :: GcDirectBarrier :: write_barrier( & value, & self , offset) ) ;
487506 extra_items. push ( quote ! {
488507 #[ inline] // TODO: Implement `GcDirectBarrier` ourselves
489- #mutator_vis fn #mutator_name<Id >( self : :: zerogc :: Gc <#gc_lifetime, Self , Id >, value: #value_ref_type)
490- where Id : :: zerogc :: CollectorId ,
491- #value_ref_type: :: zerogc :: GcDirectBarrier <#gc_lifetime, :: zerogc :: Gc <#gc_lifetime, Self , Id >> {
508+ #mutator_vis fn #mutator_name<Id >( self : ZEROGC_CRATE :: Gc <#gc_lifetime, Self , Id >, value: #value_ref_type)
509+ where Id : ZEROGC_CRATE :: CollectorId ,
510+ #value_ref_type: ZEROGC_CRATE :: GcDirectBarrier <#gc_lifetime, ZEROGC_CRATE :: Gc <#gc_lifetime, Self , Id >> {
492511 unsafe {
493512 let target_ptr = #field_as_ptr;
494513 let offset = target_ptr as usize - self . as_raw_ptr( ) as usize ;
@@ -535,13 +554,14 @@ fn impl_extras(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, E
535554
536555
537556fn impl_erase_nop ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
557+ let zerogc_crate = zerogc_crate ( ) ;
538558 let name = & target. ident ;
539559 let mut generics: Generics = target. generics . clone ( ) ;
540560 for param in & mut generics. params {
541561 match param {
542562 GenericParam :: Type ( ref mut type_param) => {
543563 // Require all params are NullTrace
544- type_param. bounds . push ( parse_quote ! ( :: zerogc :: NullTrace ) ) ;
564+ type_param. bounds . push ( parse_quote ! ( ZEROGC_CRATE :: NullTrace ) ) ;
545565 } ,
546566 GenericParam :: Lifetime ( ref mut l) => {
547567 if l. lifetime == info. config . gc_lifetime ( ) {
@@ -568,28 +588,29 @@ fn impl_erase_nop(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream
568588 let collector_id = match info. config . collector_id {
569589 Some ( ref id) => id. clone ( ) ,
570590 None => {
571- impl_generics. params . push ( GenericParam :: Type ( parse_quote ! ( Id : :: zerogc :: CollectorId ) ) ) ;
591+ impl_generics. params . push ( GenericParam :: Type ( parse_quote ! ( Id : #zerogc_crate :: CollectorId ) ) ) ;
572592 parse_quote ! ( Id )
573593 }
574594 } ;
575595 // Require that `Self: NullTrace`
576596 impl_generics. make_where_clause ( ) . predicates . push ( WherePredicate :: Type ( PredicateType {
577597 lifetimes : None ,
578598 bounded_ty : parse_quote ! ( Self ) ,
579- bounds : parse_quote ! ( :: zerogc :: NullTrace ) ,
599+ bounds : parse_quote ! ( #zerogc_crate :: NullTrace ) ,
580600 colon_token : Default :: default ( )
581601 } ) ) ;
582602 let ( _, ty_generics, _) = generics. split_for_impl ( ) ;
583603 let ( impl_generics, _, where_clause) = impl_generics. split_for_impl ( ) ;
584604 Ok ( quote ! {
585- unsafe impl #impl_generics :: zerogc :: GcErase <' min, #collector_id>
605+ unsafe impl #impl_generics #zerogc_crate :: GcErase <' min, #collector_id>
586606 for #name #ty_generics #where_clause {
587607 // We can pass-through because we are NullTrace
588608 type Erased = Self ;
589609 }
590610 } )
591611}
592612fn impl_erase ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
613+ let zerogc_crate = zerogc_crate ( ) ;
593614 let name = & target. ident ;
594615 let mut generics: Generics = target. generics . clone ( ) ;
595616 let mut rewritten_params = Vec :: new ( ) ;
@@ -603,10 +624,10 @@ fn impl_erase(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, Er
603624 match param {
604625 GenericParam :: Type ( ref mut type_param) => {
605626 let original_bounds = type_param. bounds . iter ( ) . cloned ( ) . collect :: < Vec < _ > > ( ) ;
606- type_param. bounds . push ( parse_quote ! ( :: zerogc :: GcErase <' min, #collector_id>) ) ;
627+ type_param. bounds . push ( parse_quote ! ( #zerogc_crate :: GcErase <' min, #collector_id>) ) ;
607628 type_param. bounds . push ( parse_quote ! ( ' min) ) ;
608629 let param_name = & type_param. ident ;
609- let rewritten_type: Type = parse_quote ! ( <#param_name as :: zerogc :: GcErase <' min, #collector_id>>:: Erased ) ;
630+ let rewritten_type: Type = parse_quote ! ( <#param_name as #zerogc_crate :: GcErase <' min, #collector_id>>:: Erased ) ;
610631 rewritten_restrictions. push ( WherePredicate :: Type ( PredicateType {
611632 lifetimes : None ,
612633 bounded_ty : rewritten_type. clone ( ) ,
@@ -654,17 +675,17 @@ fn impl_erase(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, Er
654675 let mut impl_generics = generics. clone ( ) ;
655676 impl_generics. params . push ( GenericParam :: Lifetime ( parse_quote ! ( ' min) ) ) ;
656677 if info. config . collector_id . is_none ( ) {
657- impl_generics. params . push ( GenericParam :: Type ( parse_quote ! ( Id : :: zerogc :: CollectorId ) ) ) ;
678+ impl_generics. params . push ( GenericParam :: Type ( parse_quote ! ( Id : #zerogc_crate :: CollectorId ) ) ) ;
658679 }
659680 impl_generics. make_where_clause ( ) . predicates . extend ( rewritten_restrictions) ;
660681 let ( _, ty_generics, _) = generics. split_for_impl ( ) ;
661682 let ( impl_generics, _, where_clause) = impl_generics. split_for_impl ( ) ;
662683 let assert_erase = field_types. iter ( ) . map ( |field_type| {
663684 let span = field_type. span ( ) ;
664- quote_spanned ! ( span => <#field_type as :: zerogc :: GcErase <' min, #collector_id>>:: assert_erase( ) ; )
685+ quote_spanned ! ( span => <#field_type as #zerogc_crate :: GcErase <' min, #collector_id>>:: assert_erase( ) ; )
665686 } ) . collect :: < Vec < _ > > ( ) ;
666687 Ok ( quote ! {
667- unsafe impl #impl_generics :: zerogc :: GcErase <' min, #collector_id>
688+ unsafe impl #impl_generics #zerogc_crate :: GcErase <' min, #collector_id>
668689 for #name #ty_generics #where_clause {
669690 type Erased = #name:: <#( #rewritten_params) , * >;
670691
@@ -677,13 +698,14 @@ fn impl_erase(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, Er
677698
678699
679700fn impl_rebrand_nop ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
701+ let zerogc_crate = zerogc_crate ( ) ;
680702 let name = & target. ident ;
681703 let mut generics: Generics = target. generics . clone ( ) ;
682704 for param in & mut generics. params {
683705 match param {
684706 GenericParam :: Type ( ref mut type_param) => {
685707 // Require all params are NullTrace
686- type_param. bounds . push ( parse_quote ! ( :: zerogc :: NullTrace ) ) ;
708+ type_param. bounds . push ( parse_quote ! ( #zerogc_crate :: NullTrace ) ) ;
687709 } ,
688710 GenericParam :: Lifetime ( ref mut l) => {
689711 if l. lifetime == info. config . gc_lifetime ( ) {
@@ -710,28 +732,29 @@ fn impl_rebrand_nop(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStre
710732 let collector_id = match info. config . collector_id {
711733 Some ( ref id) => id. clone ( ) ,
712734 None => {
713- impl_generics. params . push ( GenericParam :: Type ( parse_quote ! ( Id : :: zerogc :: CollectorId ) ) ) ;
735+ impl_generics. params . push ( GenericParam :: Type ( parse_quote ! ( Id : #zerogc_crate :: CollectorId ) ) ) ;
714736 parse_quote ! ( Id )
715737 }
716738 } ;
717739 // Require that `Self: NullTrace`
718740 impl_generics. make_where_clause ( ) . predicates . push ( WherePredicate :: Type ( PredicateType {
719741 lifetimes : None ,
720742 bounded_ty : parse_quote ! ( Self ) ,
721- bounds : parse_quote ! ( :: zerogc :: NullTrace ) ,
743+ bounds : parse_quote ! ( #zerogc_crate :: NullTrace ) ,
722744 colon_token : Default :: default ( )
723745 } ) ) ;
724746 let ( _, ty_generics, _) = generics. split_for_impl ( ) ;
725747 let ( impl_generics, _, where_clause) = impl_generics. split_for_impl ( ) ;
726748 Ok ( quote ! {
727- unsafe impl #impl_generics :: zerogc :: GcRebrand <' new_gc, #collector_id>
749+ unsafe impl #impl_generics #zerogc_crate :: GcRebrand <' new_gc, #collector_id>
728750 for #name #ty_generics #where_clause {
729751 // We can pass-through because we are NullTrace
730752 type Branded = Self ;
731753 }
732754 } )
733755}
734756fn impl_rebrand ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
757+ let zerogc_crate = zerogc_crate ( ) ;
735758 let name = & target. ident ;
736759 let mut generics: Generics = target. generics . clone ( ) ;
737760 let mut rewritten_params = Vec :: new ( ) ;
@@ -745,9 +768,9 @@ fn impl_rebrand(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
745768 match param {
746769 GenericParam :: Type ( ref mut type_param) => {
747770 let original_bounds = type_param. bounds . iter ( ) . cloned ( ) . collect :: < Vec < _ > > ( ) ;
748- type_param. bounds . push ( parse_quote ! ( :: zerogc :: GcRebrand <' new_gc, #collector_id>) ) ;
771+ type_param. bounds . push ( parse_quote ! ( #zerogc_crate :: GcRebrand <' new_gc, #collector_id>) ) ;
749772 let param_name = & type_param. ident ;
750- let rewritten_type: Type = parse_quote ! ( <#param_name as :: zerogc :: GcRebrand <' new_gc, #collector_id>>:: Branded ) ;
773+ let rewritten_type: Type = parse_quote ! ( <#param_name as #zerogc_crate :: GcRebrand <' new_gc, #collector_id>>:: Branded ) ;
751774 rewritten_restrictions. push ( WherePredicate :: Type ( PredicateType {
752775 lifetimes : None ,
753776 bounded_ty : rewritten_type. clone ( ) ,
@@ -795,17 +818,17 @@ fn impl_rebrand(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
795818 let mut impl_generics = generics. clone ( ) ;
796819 impl_generics. params . push ( GenericParam :: Lifetime ( parse_quote ! ( ' new_gc) ) ) ;
797820 if info. config . collector_id . is_none ( ) {
798- impl_generics. params . push ( GenericParam :: Type ( parse_quote ! ( Id : :: zerogc :: CollectorId ) ) ) ;
821+ impl_generics. params . push ( GenericParam :: Type ( parse_quote ! ( Id : #zerogc_crate :: CollectorId ) ) ) ;
799822 }
800823 let assert_rebrand = field_types. iter ( ) . map ( |field_type| {
801824 let span = field_type. span ( ) ;
802- quote_spanned ! ( span => <#field_type as :: zerogc :: GcRebrand <' new_gc, #collector_id>>:: assert_rebrand( ) ; )
825+ quote_spanned ! ( span => <#field_type as #zerogc_crate :: GcRebrand <' new_gc, #collector_id>>:: assert_rebrand( ) ; )
803826 } ) . collect :: < Vec < _ > > ( ) ;
804827 impl_generics. make_where_clause ( ) . predicates . extend ( rewritten_restrictions) ;
805828 let ( _, ty_generics, _) = generics. split_for_impl ( ) ;
806829 let ( impl_generics, _, where_clause) = impl_generics. split_for_impl ( ) ;
807830 Ok ( quote ! {
808- unsafe impl #impl_generics :: zerogc :: GcRebrand <' new_gc, #collector_id>
831+ unsafe impl #impl_generics #zerogc_crate :: GcRebrand <' new_gc, #collector_id>
809832 for #name #ty_generics #where_clause {
810833 type Branded = #name:: <#( #rewritten_params) , * >;
811834
@@ -816,6 +839,7 @@ fn impl_rebrand(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
816839 } )
817840}
818841fn impl_trace ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
842+ let zerogc_crate = zerogc_crate ( ) ;
819843 let name = & target. ident ;
820844 let generics = add_trait_bounds_except (
821845 & target. generics , parse_quote ! ( zerogc:: Trace ) ,
@@ -884,26 +908,27 @@ fn impl_trace(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, Er
884908 } ,
885909 }
886910 Ok ( quote ! {
887- unsafe impl #impl_generics :: zerogc :: Trace for #name #ty_generics #where_clause {
888- const NEEDS_TRACE : bool = false #( || <#field_types as :: zerogc :: Trace >:: NEEDS_TRACE ) * ;
911+ unsafe impl #impl_generics #zerogc_crate :: Trace for #name #ty_generics #where_clause {
912+ const NEEDS_TRACE : bool = false #( || <#field_types as #zerogc_crate :: Trace >:: NEEDS_TRACE ) * ;
889913
890914 /*
891915 * The inline annotation adds this function's MIR to the metadata.
892916 * Without it cross-crate inlining is impossible (without LTO).
893917 */
894918 #[ inline]
895- fn visit<V : :: zerogc :: GcVisitor >( & mut self , #[ allow( unused) ] visitor: & mut V ) -> Result <( ) , V :: Err > {
919+ fn visit<Visitor : #zerogc_crate :: GcVisitor + ? Sized >( & mut self , #[ allow( unused) ] visitor: & mut Visitor ) -> Result <( ) , Visitor :: Err > {
896920 #trace_impl
897921 Ok ( ( ) )
898922 }
899923 }
900924 } )
901925}
902926fn impl_gc_safe ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
927+ let zerogc_crate = zerogc_crate ( ) ;
903928 let name = & target. ident ;
904929 let collector_id = & info. config . collector_id ;
905930 let generics = add_trait_bounds_except (
906- & target. generics , parse_quote ! ( zerogc :: GcSafe ) ,
931+ & target. generics , parse_quote ! ( #zerogc_crate :: GcSafe ) ,
907932 & info. config . ignore_params ,
908933 Some ( & mut |other : & Ident | {
909934 if let Some ( ref collector_id) = * collector_id {
@@ -936,7 +961,7 @@ fn impl_gc_safe(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
936961 quote ! ( false )
937962 } else {
938963 // We need to be dropped if any of our fields need to be dropped
939- quote ! ( false #( || <#field_types as :: zerogc :: GcSafe >:: NEEDS_DROP ) * )
964+ quote ! ( false #( || <#field_types as #zerogc_crate :: GcSafe >:: NEEDS_DROP ) * )
940965 } ;
941966 let fake_drop_impl = if info. config . is_copy {
942967 /*
@@ -959,12 +984,12 @@ fn impl_gc_safe(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
959984 } )
960985 } ;
961986 let verify_gc_safe = if info. config . is_copy {
962- quote ! ( :: zerogc :: assert_copy:: <Self >( ) )
987+ quote ! ( #zerogc_crate :: assert_copy:: <Self >( ) )
963988 } else {
964- quote ! ( #( <#field_types as GcSafe >:: assert_gc_safe( ) ; ) * )
989+ quote ! ( #( <#field_types as #zerogc_crate :: GcSafe >:: assert_gc_safe( ) ; ) * )
965990 } ;
966991 Ok ( quote ! {
967- unsafe impl #impl_generics :: zerogc :: GcSafe
992+ unsafe impl #impl_generics #zerogc_crate :: GcSafe
968993 for #name #ty_generics #where_clause {
969994 const NEEDS_DROP : bool = #does_need_drop;
970995
@@ -978,9 +1003,10 @@ fn impl_gc_safe(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
9781003
9791004
9801005fn impl_nop_trace ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
1006+ let zerogc_crate = zerogc_crate ( ) ;
9811007 let name = & target. ident ;
9821008 let generics = add_trait_bounds_except (
983- & target. generics , parse_quote ! ( zerogc :: Trace ) ,
1009+ & target. generics , parse_quote ! ( #zerogc_crate :: Trace ) ,
9841010 & info. config . ignore_params , None
9851011 ) ?;
9861012 let ( impl_generics, ty_generics, where_clause) = generics. split_for_impl ( ) ;
@@ -1007,30 +1033,30 @@ fn impl_nop_trace(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream
10071033 let ty_span = t. span ( ) ;
10081034 quote_spanned ! { ty_span =>
10091035 assert!(
1010- !<#t as Trace >:: NEEDS_TRACE ,
1036+ !<#t as #zerogc_crate :: Trace >:: NEEDS_TRACE ,
10111037 "Can't #[derive(NullTrace) with {}" ,
10121038 stringify!( #t)
10131039 ) ;
10141040 }
10151041 } ) . collect :: < Vec < _ > > ( ) ;
10161042 Ok ( quote ! {
1017- unsafe impl #impl_generics :: zerogc :: Trace for #name #ty_generics #where_clause {
1043+ unsafe impl #impl_generics #zerogc_crate :: Trace for #name #ty_generics #where_clause {
10181044 const NEEDS_TRACE : bool = false ;
10191045
10201046 #[ inline] // Should be const-folded away
1021- fn visit<V : :: zerogc :: GcVisitor >( & mut self , #[ allow( unused) ] visitor: & mut V ) -> Result <( ) , V :: Err > {
1047+ fn visit<Visitor : #zerogc_crate :: GcVisitor + ? Sized >( & mut self , #[ allow( unused) ] visitor: & mut Visitor ) -> Result <( ) , Visitor :: Err > {
10221048 #( #trace_assertions) *
10231049 Ok ( ( ) )
10241050 }
10251051 }
1026- unsafe impl #impl_generics :: zerogc :: TraceImmutable for #name #ty_generics #where_clause {
1052+ unsafe impl #impl_generics #zerogc_crate :: TraceImmutable for #name #ty_generics #where_clause {
10271053 #[ inline] // Should be const-folded away
1028- fn visit_immutable<V : :: zerogc :: GcVisitor >( & self , #[ allow( unused) ] visitor: & mut V ) -> Result <( ) , V :: Err > {
1054+ fn visit_immutable<Visitor : #zerogc_crate :: GcVisitor + ? Sized >( & self , #[ allow( unused) ] visitor: & mut Visitor ) -> Result <( ) , Visitor :: Err > {
10291055 #( #trace_assertions) *
10301056 Ok ( ( ) )
10311057 }
10321058 }
1033- unsafe impl #impl_generics :: zerogc :: NullTrace for #name #ty_generics #where_clause { }
1059+ unsafe impl #impl_generics #zerogc_crate :: NullTrace for #name #ty_generics #where_clause { }
10341060 } )
10351061}
10361062
0 commit comments