@@ -86,7 +86,7 @@ macro_rules! safepoint_recurse {
86
86
* We trust that GcContext::recurse_context
87
87
* did not perform a collection after calling the closure.
88
88
*/
89
- let result = unsafe { $context. rebrand_self( erased_result) } ;
89
+ let result = unsafe { $context. rebrand_self( * * erased_result) } ;
90
90
safepoint!( $context, ( root, result) )
91
91
} } ;
92
92
}
@@ -117,7 +117,7 @@ macro_rules! __recurse_context {
117
117
* NOTE: Guarenteed to live for the lifetime of the entire closure.
118
118
* However, it could be relocated if 'sub_collector' is collected
119
119
*/
120
- let $new_root = $sub_context. rebrand_self( erased_root) ;
120
+ let $new_root = $sub_context. rebrand_self( * erased_root) ;
121
121
$closure
122
122
} )
123
123
} } ;
@@ -208,11 +208,11 @@ pub unsafe trait GcSystem {
208
208
/// This type-system hackery is needed because
209
209
/// we need to place bounds on `T as GcBrand`
210
210
// TODO: Remove when we get more powerful types
211
- pub unsafe trait GcHandleSystem < ' gc , T : GcSafe + ?Sized + ' gc > : GcSystem
212
- where T : GcBrand < ' static , Self :: Id > ,
213
- <T as GcBrand < ' static , Self :: Id > >:: Branded : GcSafe {
211
+ pub unsafe trait GcHandleSystem < ' gc , ' a , T : GcSafe + ?Sized + ' gc > : GcSystem
212
+ where T : GcErase < ' a , Self :: Id > ,
213
+ <T as GcErase < ' a , Self :: Id > >:: Erased : GcSafe {
214
214
/// The type of handles to this object.
215
- type Handle : GcHandle < <T as GcBrand < ' static , Self :: Id > >:: Branded , System =Self > ;
215
+ type Handle : GcHandle < <T as GcErase < ' a , Self :: Id > >:: Erased , System =Self > ;
216
216
217
217
/// Create a handle to the specified GC pointer,
218
218
/// which can be used without a context
@@ -281,16 +281,16 @@ pub unsafe trait GcContext: Sized {
281
281
282
282
#[ inline( always) ]
283
283
#[ doc( hidden) ]
284
- unsafe fn rebrand_static < T > ( & self , value : T ) -> T :: Branded
285
- where T : GcBrand < ' static , Self :: Id > {
284
+ unsafe fn rebrand_static < ' a , T > ( & self , value : T ) -> T :: Erased
285
+ where T : GcErase < ' a , Self :: Id > {
286
286
let branded = mem:: transmute_copy ( & value) ;
287
287
mem:: forget ( value) ;
288
288
branded
289
289
}
290
290
#[ inline( always) ]
291
291
#[ doc( hidden) ]
292
- unsafe fn rebrand_self < ' a , T > ( & ' a self , value : T ) -> T :: Branded
293
- where T : GcBrand < ' a , Self :: Id > {
292
+ unsafe fn rebrand_self < ' gc , T > ( & ' gc self , value : T ) -> T :: Branded
293
+ where T : GcRebrand < ' gc , Self :: Id > {
294
294
let branded = mem:: transmute_copy ( & value) ;
295
295
mem:: forget ( value) ;
296
296
branded
@@ -414,6 +414,10 @@ pub struct Gc<'gc, T: GcSafe + ?Sized + 'gc, Id: CollectorId> {
414
414
/// Used to uniquely identify the collector,
415
415
/// to ensure we aren't modifying another collector's pointers
416
416
collector_id : Id ,
417
+ /*
418
+ * TODO: I think this lifetime variance is safe
419
+ * Better add some tests and an explination.
420
+ */
417
421
marker : PhantomData < & ' gc T > ,
418
422
}
419
423
impl < ' gc , T : GcSafe + ?Sized + ' gc , Id : CollectorId > Gc < ' gc , T , Id > {
@@ -447,11 +451,11 @@ impl<'gc, T: GcSafe + ?Sized + 'gc, Id: CollectorId> Gc<'gc, T, Id> {
447
451
448
452
/// Create a handle to this object, which can be used without a context
449
453
#[ inline]
450
- pub fn create_handle ( & self ) -> <Id :: System as GcHandleSystem < ' gc , T > >:: Handle
451
- where Id :: System : GcHandleSystem < ' gc , T > ,
452
- T : GcBrand < ' static , Id > ,
453
- <T as GcBrand < ' static , Id > >:: Branded : GcSafe {
454
- <Id :: System as GcHandleSystem < ' gc , T > >:: create_handle ( * self )
454
+ pub fn create_handle < ' a > ( & self ) -> <Id :: System as GcHandleSystem < ' gc , ' a , T > >:: Handle
455
+ where Id :: System : GcHandleSystem < ' gc , ' a , T > ,
456
+ T : GcErase < ' a , Id > + ' a ,
457
+ <T as GcErase < ' a , Id > >:: Erased : GcSafe + ' a {
458
+ <Id :: System as GcHandleSystem < ' gc , ' a , T > >:: create_handle ( * self )
455
459
}
456
460
457
461
/// Get a reference to the system
@@ -481,10 +485,17 @@ unsafe impl<'gc, T: GcSafe + 'gc, Id: CollectorId> GcSafe for Gc<'gc, T, Id> {
481
485
const NEEDS_DROP : bool = true ; // We are Copy
482
486
}
483
487
/// Rebrand
484
- unsafe impl < ' gc , ' new_gc , T , Id > GcBrand < ' new_gc , Id > for Gc < ' gc , T , Id >
485
- where T : GcSafe + GcBrand < ' new_gc , Id > ,
486
- T :: Branded : GcSafe , Id : CollectorId {
487
- type Branded = Gc < ' new_gc , <T as GcBrand < ' new_gc , Id > >:: Branded , Id > ;
488
+ unsafe impl < ' gc , ' new_gc , T , Id > GcRebrand < ' new_gc , Id > for Gc < ' gc , T , Id >
489
+ where T : GcSafe + GcRebrand < ' new_gc , Id > ,
490
+ <T as GcRebrand < ' new_gc , Id > >:: Branded : GcSafe ,
491
+ Id : CollectorId , {
492
+ type Branded = Gc < ' new_gc , <T as GcRebrand < ' new_gc , Id > >:: Branded , Id > ;
493
+ }
494
+ unsafe impl < ' gc , ' a , T , Id > GcErase < ' a , Id > for Gc < ' gc , T , Id >
495
+ where T : GcSafe + GcErase < ' a , Id > ,
496
+ <T as GcErase < ' a , Id > >:: Erased : GcSafe ,
497
+ Id : CollectorId , {
498
+ type Erased = Gc < ' a , <T as GcErase < ' a , Id > >:: Erased , Id > ;
488
499
}
489
500
unsafe impl < ' gc , T : GcSafe + ' gc , Id : CollectorId > Trace for Gc < ' gc , T , Id > {
490
501
// We always need tracing....
@@ -626,8 +637,8 @@ pub unsafe trait GcHandle<T: GcSafe + ?Sized>: Clone + NullTrace {
626
637
///
627
638
/// TODO: Remove when we get more powerful types
628
639
pub unsafe trait GcBindHandle < ' new_gc , T : GcSafe + ?Sized > : GcHandle < T >
629
- where T : GcBrand < ' new_gc , Self :: Id > ,
630
- <T as GcBrand < ' new_gc , Self :: Id > >:: Branded : GcSafe {
640
+ where T : GcRebrand < ' new_gc , Self :: Id > ,
641
+ <T as GcRebrand < ' new_gc , Self :: Id > >:: Branded : GcSafe {
631
642
/// Associate this handle with the specified context,
632
643
/// allowing its underlying object to be accessed
633
644
/// as long as the context is valid.
@@ -638,7 +649,7 @@ pub unsafe trait GcBindHandle<'new_gc, T: GcSafe + ?Sized>: GcHandle<T>
638
649
/// at the next safepoint.
639
650
fn bind_to ( & self , context : & ' new_gc <Self :: System as GcSystem >:: Context ) -> Gc <
640
651
' new_gc ,
641
- <T as GcBrand < ' new_gc , Self :: Id > >:: Branded ,
652
+ <T as GcRebrand < ' new_gc , Self :: Id > >:: Branded ,
642
653
Self :: Id
643
654
> ;
644
655
}
@@ -777,19 +788,34 @@ unsafe impl<T> GcSafe for AssumeNotTraced<T> {
777
788
}
778
789
unsafe_gc_brand ! ( AssumeNotTraced , T ) ;
779
790
780
- /// Changes all references to garbage
781
- /// collected objects to match `'new_gc` .
791
+ /// Changes all references to garbage collected
792
+ /// objects to match a specific lifetime .
782
793
///
783
794
/// This indicates that its safe to transmute to the new `Branded` type
784
795
/// and all that will change is the lifetimes.
785
- pub unsafe trait GcBrand < ' new_gc , Id : CollectorId > : Trace {
796
+ // TODO: Can we support lifetimes that are smaller than 'new_gc
797
+ pub unsafe trait GcRebrand < ' new_gc , Id : CollectorId > : Trace {
786
798
/// This type with all garbage collected lifetimes
787
799
/// changed to `'new_gc`
788
800
///
789
801
/// This must have the same in-memory repr as `Self`,
790
802
/// so that it's safe to transmute.
791
803
type Branded : Trace + ' new_gc ;
792
804
}
805
+ /// Indicates that it's safe to erase all GC lifetimes
806
+ /// and change them to 'static (logically an 'unsafe)
807
+ ///
808
+ /// This trait is the opposite of [GcRebrand]
809
+ ///
810
+ /// The lifetime '`a` is the minimum lifetime of all other non-gc references.
811
+ pub unsafe trait GcErase < ' a , Id : CollectorId > : Trace {
812
+ /// This type with all garbage collected lifetimes
813
+ /// changed to `'static` (or erased)
814
+ ///
815
+ /// This must have the same in-memory repr as `Self`,
816
+ /// so that it's safe to transmute.
817
+ type Erased : ' a ;
818
+ }
793
819
794
820
/// Indicates that a type can be traced by a garbage collector.
795
821
///
0 commit comments