@@ -15,6 +15,24 @@ use std::io::Write;
15
15
16
16
mod macros;
17
17
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
+
18
36
struct MutableFieldOpts {
19
37
public : bool
20
38
}
@@ -410,14 +428,15 @@ fn impl_derive_trace(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
410
428
}
411
429
412
430
fn trace_fields ( fields : & Fields , access_ref : & mut dyn FnMut ( Member ) -> TokenStream ) -> TokenStream {
431
+ let zerogc_crate = zerogc_crate ( ) ;
413
432
// TODO: Detect if we're a unit struct and implement `NullTrace`
414
433
let mut result = Vec :: new ( ) ;
415
434
for ( index, field) in fields. iter ( ) . enumerate ( ) {
416
435
let val = access_ref ( match field. ident {
417
436
Some ( ref ident) => Member :: Named ( ident. clone ( ) ) ,
418
437
None => Member :: Unnamed ( Index :: from ( index) )
419
438
} ) ;
420
- result. push ( quote ! ( :: zerogc :: Trace :: visit( #val, & mut * visitor) ?) ) ;
439
+ result. push ( quote ! ( #zerogc_crate :: Trace :: visit( #val, & mut * visitor) ?) ) ;
421
440
}
422
441
quote ! ( #( #result; ) * )
423
442
}
@@ -482,13 +501,13 @@ fn impl_extras(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, E
482
501
) )
483
502
} ;
484
503
// 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) ) ;
487
506
extra_items. push ( quote ! {
488
507
#[ 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 >> {
492
511
unsafe {
493
512
let target_ptr = #field_as_ptr;
494
513
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
535
554
536
555
537
556
fn impl_erase_nop ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
557
+ let zerogc_crate = zerogc_crate ( ) ;
538
558
let name = & target. ident ;
539
559
let mut generics: Generics = target. generics . clone ( ) ;
540
560
for param in & mut generics. params {
541
561
match param {
542
562
GenericParam :: Type ( ref mut type_param) => {
543
563
// Require all params are NullTrace
544
- type_param. bounds . push ( parse_quote ! ( :: zerogc :: NullTrace ) ) ;
564
+ type_param. bounds . push ( parse_quote ! ( ZEROGC_CRATE :: NullTrace ) ) ;
545
565
} ,
546
566
GenericParam :: Lifetime ( ref mut l) => {
547
567
if l. lifetime == info. config . gc_lifetime ( ) {
@@ -568,28 +588,29 @@ fn impl_erase_nop(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream
568
588
let collector_id = match info. config . collector_id {
569
589
Some ( ref id) => id. clone ( ) ,
570
590
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 ) ) ) ;
572
592
parse_quote ! ( Id )
573
593
}
574
594
} ;
575
595
// Require that `Self: NullTrace`
576
596
impl_generics. make_where_clause ( ) . predicates . push ( WherePredicate :: Type ( PredicateType {
577
597
lifetimes : None ,
578
598
bounded_ty : parse_quote ! ( Self ) ,
579
- bounds : parse_quote ! ( :: zerogc :: NullTrace ) ,
599
+ bounds : parse_quote ! ( #zerogc_crate :: NullTrace ) ,
580
600
colon_token : Default :: default ( )
581
601
} ) ) ;
582
602
let ( _, ty_generics, _) = generics. split_for_impl ( ) ;
583
603
let ( impl_generics, _, where_clause) = impl_generics. split_for_impl ( ) ;
584
604
Ok ( quote ! {
585
- unsafe impl #impl_generics :: zerogc :: GcErase <' min, #collector_id>
605
+ unsafe impl #impl_generics #zerogc_crate :: GcErase <' min, #collector_id>
586
606
for #name #ty_generics #where_clause {
587
607
// We can pass-through because we are NullTrace
588
608
type Erased = Self ;
589
609
}
590
610
} )
591
611
}
592
612
fn impl_erase ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
613
+ let zerogc_crate = zerogc_crate ( ) ;
593
614
let name = & target. ident ;
594
615
let mut generics: Generics = target. generics . clone ( ) ;
595
616
let mut rewritten_params = Vec :: new ( ) ;
@@ -603,10 +624,10 @@ fn impl_erase(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, Er
603
624
match param {
604
625
GenericParam :: Type ( ref mut type_param) => {
605
626
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>) ) ;
607
628
type_param. bounds . push ( parse_quote ! ( ' min) ) ;
608
629
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 ) ;
610
631
rewritten_restrictions. push ( WherePredicate :: Type ( PredicateType {
611
632
lifetimes : None ,
612
633
bounded_ty : rewritten_type. clone ( ) ,
@@ -654,17 +675,17 @@ fn impl_erase(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, Er
654
675
let mut impl_generics = generics. clone ( ) ;
655
676
impl_generics. params . push ( GenericParam :: Lifetime ( parse_quote ! ( ' min) ) ) ;
656
677
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 ) ) ) ;
658
679
}
659
680
impl_generics. make_where_clause ( ) . predicates . extend ( rewritten_restrictions) ;
660
681
let ( _, ty_generics, _) = generics. split_for_impl ( ) ;
661
682
let ( impl_generics, _, where_clause) = impl_generics. split_for_impl ( ) ;
662
683
let assert_erase = field_types. iter ( ) . map ( |field_type| {
663
684
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( ) ; )
665
686
} ) . collect :: < Vec < _ > > ( ) ;
666
687
Ok ( quote ! {
667
- unsafe impl #impl_generics :: zerogc :: GcErase <' min, #collector_id>
688
+ unsafe impl #impl_generics #zerogc_crate :: GcErase <' min, #collector_id>
668
689
for #name #ty_generics #where_clause {
669
690
type Erased = #name:: <#( #rewritten_params) , * >;
670
691
@@ -677,13 +698,14 @@ fn impl_erase(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, Er
677
698
678
699
679
700
fn impl_rebrand_nop ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
701
+ let zerogc_crate = zerogc_crate ( ) ;
680
702
let name = & target. ident ;
681
703
let mut generics: Generics = target. generics . clone ( ) ;
682
704
for param in & mut generics. params {
683
705
match param {
684
706
GenericParam :: Type ( ref mut type_param) => {
685
707
// Require all params are NullTrace
686
- type_param. bounds . push ( parse_quote ! ( :: zerogc :: NullTrace ) ) ;
708
+ type_param. bounds . push ( parse_quote ! ( #zerogc_crate :: NullTrace ) ) ;
687
709
} ,
688
710
GenericParam :: Lifetime ( ref mut l) => {
689
711
if l. lifetime == info. config . gc_lifetime ( ) {
@@ -710,28 +732,29 @@ fn impl_rebrand_nop(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStre
710
732
let collector_id = match info. config . collector_id {
711
733
Some ( ref id) => id. clone ( ) ,
712
734
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 ) ) ) ;
714
736
parse_quote ! ( Id )
715
737
}
716
738
} ;
717
739
// Require that `Self: NullTrace`
718
740
impl_generics. make_where_clause ( ) . predicates . push ( WherePredicate :: Type ( PredicateType {
719
741
lifetimes : None ,
720
742
bounded_ty : parse_quote ! ( Self ) ,
721
- bounds : parse_quote ! ( :: zerogc :: NullTrace ) ,
743
+ bounds : parse_quote ! ( #zerogc_crate :: NullTrace ) ,
722
744
colon_token : Default :: default ( )
723
745
} ) ) ;
724
746
let ( _, ty_generics, _) = generics. split_for_impl ( ) ;
725
747
let ( impl_generics, _, where_clause) = impl_generics. split_for_impl ( ) ;
726
748
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>
728
750
for #name #ty_generics #where_clause {
729
751
// We can pass-through because we are NullTrace
730
752
type Branded = Self ;
731
753
}
732
754
} )
733
755
}
734
756
fn impl_rebrand ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
757
+ let zerogc_crate = zerogc_crate ( ) ;
735
758
let name = & target. ident ;
736
759
let mut generics: Generics = target. generics . clone ( ) ;
737
760
let mut rewritten_params = Vec :: new ( ) ;
@@ -745,9 +768,9 @@ fn impl_rebrand(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
745
768
match param {
746
769
GenericParam :: Type ( ref mut type_param) => {
747
770
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>) ) ;
749
772
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 ) ;
751
774
rewritten_restrictions. push ( WherePredicate :: Type ( PredicateType {
752
775
lifetimes : None ,
753
776
bounded_ty : rewritten_type. clone ( ) ,
@@ -795,17 +818,17 @@ fn impl_rebrand(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
795
818
let mut impl_generics = generics. clone ( ) ;
796
819
impl_generics. params . push ( GenericParam :: Lifetime ( parse_quote ! ( ' new_gc) ) ) ;
797
820
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 ) ) ) ;
799
822
}
800
823
let assert_rebrand = field_types. iter ( ) . map ( |field_type| {
801
824
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( ) ; )
803
826
} ) . collect :: < Vec < _ > > ( ) ;
804
827
impl_generics. make_where_clause ( ) . predicates . extend ( rewritten_restrictions) ;
805
828
let ( _, ty_generics, _) = generics. split_for_impl ( ) ;
806
829
let ( impl_generics, _, where_clause) = impl_generics. split_for_impl ( ) ;
807
830
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>
809
832
for #name #ty_generics #where_clause {
810
833
type Branded = #name:: <#( #rewritten_params) , * >;
811
834
@@ -816,6 +839,7 @@ fn impl_rebrand(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
816
839
} )
817
840
}
818
841
fn impl_trace ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
842
+ let zerogc_crate = zerogc_crate ( ) ;
819
843
let name = & target. ident ;
820
844
let generics = add_trait_bounds_except (
821
845
& target. generics , parse_quote ! ( zerogc:: Trace ) ,
@@ -884,26 +908,27 @@ fn impl_trace(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream, Er
884
908
} ,
885
909
}
886
910
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 ) * ;
889
913
890
914
/*
891
915
* The inline annotation adds this function's MIR to the metadata.
892
916
* Without it cross-crate inlining is impossible (without LTO).
893
917
*/
894
918
#[ 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 > {
896
920
#trace_impl
897
921
Ok ( ( ) )
898
922
}
899
923
}
900
924
} )
901
925
}
902
926
fn impl_gc_safe ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
927
+ let zerogc_crate = zerogc_crate ( ) ;
903
928
let name = & target. ident ;
904
929
let collector_id = & info. config . collector_id ;
905
930
let generics = add_trait_bounds_except (
906
- & target. generics , parse_quote ! ( zerogc :: GcSafe ) ,
931
+ & target. generics , parse_quote ! ( #zerogc_crate :: GcSafe ) ,
907
932
& info. config . ignore_params ,
908
933
Some ( & mut |other : & Ident | {
909
934
if let Some ( ref collector_id) = * collector_id {
@@ -936,7 +961,7 @@ fn impl_gc_safe(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
936
961
quote ! ( false )
937
962
} else {
938
963
// 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 ) * )
940
965
} ;
941
966
let fake_drop_impl = if info. config . is_copy {
942
967
/*
@@ -959,12 +984,12 @@ fn impl_gc_safe(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
959
984
} )
960
985
} ;
961
986
let verify_gc_safe = if info. config . is_copy {
962
- quote ! ( :: zerogc :: assert_copy:: <Self >( ) )
987
+ quote ! ( #zerogc_crate :: assert_copy:: <Self >( ) )
963
988
} else {
964
- quote ! ( #( <#field_types as GcSafe >:: assert_gc_safe( ) ; ) * )
989
+ quote ! ( #( <#field_types as #zerogc_crate :: GcSafe >:: assert_gc_safe( ) ; ) * )
965
990
} ;
966
991
Ok ( quote ! {
967
- unsafe impl #impl_generics :: zerogc :: GcSafe
992
+ unsafe impl #impl_generics #zerogc_crate :: GcSafe
968
993
for #name #ty_generics #where_clause {
969
994
const NEEDS_DROP : bool = #does_need_drop;
970
995
@@ -978,9 +1003,10 @@ fn impl_gc_safe(target: &DeriveInput, info: &GcTypeInfo) -> Result<TokenStream,
978
1003
979
1004
980
1005
fn impl_nop_trace ( target : & DeriveInput , info : & GcTypeInfo ) -> Result < TokenStream , Error > {
1006
+ let zerogc_crate = zerogc_crate ( ) ;
981
1007
let name = & target. ident ;
982
1008
let generics = add_trait_bounds_except (
983
- & target. generics , parse_quote ! ( zerogc :: Trace ) ,
1009
+ & target. generics , parse_quote ! ( #zerogc_crate :: Trace ) ,
984
1010
& info. config . ignore_params , None
985
1011
) ?;
986
1012
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
1007
1033
let ty_span = t. span ( ) ;
1008
1034
quote_spanned ! { ty_span =>
1009
1035
assert!(
1010
- !<#t as Trace >:: NEEDS_TRACE ,
1036
+ !<#t as #zerogc_crate :: Trace >:: NEEDS_TRACE ,
1011
1037
"Can't #[derive(NullTrace) with {}" ,
1012
1038
stringify!( #t)
1013
1039
) ;
1014
1040
}
1015
1041
} ) . collect :: < Vec < _ > > ( ) ;
1016
1042
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 {
1018
1044
const NEEDS_TRACE : bool = false ;
1019
1045
1020
1046
#[ 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 > {
1022
1048
#( #trace_assertions) *
1023
1049
Ok ( ( ) )
1024
1050
}
1025
1051
}
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 {
1027
1053
#[ 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 > {
1029
1055
#( #trace_assertions) *
1030
1056
Ok ( ( ) )
1031
1057
}
1032
1058
}
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 { }
1034
1060
} )
1035
1061
}
1036
1062
0 commit comments