@@ -602,62 +602,73 @@ macro_rules! which_arena_for_type {
602
602
603
603
#[ macro_export]
604
604
macro_rules! declare_arena {
605
- ( [ ] , [ $( $a: tt $name: ident: $ty: ty, $gen_ty : ty; ) * ] , $tcx: lifetime) => {
605
+ ( [ ] , [ $( $a: tt $name: ident: $ty: ty, $_gen_ty : ty; ) * ] , $tcx: lifetime) => {
606
606
#[ derive( Default ) ]
607
607
pub struct Arena <$tcx> {
608
608
pub dropless: $crate:: DroplessArena ,
609
609
drop: $crate:: DropArena ,
610
610
$( $name: $crate:: arena_for_type!( $a[ $ty] ) , ) *
611
611
}
612
612
613
- #[ marker]
614
- pub trait ArenaAllocatable <' tcx> { }
615
-
616
- impl <' tcx, T : Copy > ArenaAllocatable <' tcx> for T { }
617
-
618
- unsafe trait ArenaField <' tcx>: Sized + ArenaAllocatable <' tcx> {
619
- /// Returns a specific arena to allocate from.
620
- /// If `None` is returned, the `DropArena` will be used.
621
- fn arena<' a>( arena: & ' a Arena <' tcx>) -> Option <& ' a $crate:: TypedArena <Self >>;
613
+ pub trait ArenaAllocatable <' tcx, T = Self >: Sized {
614
+ fn allocate_on<' a>( self , arena: & ' a Arena <' tcx>) -> & ' a mut Self ;
615
+ fn allocate_from_iter<' a>(
616
+ arena: & ' a Arena <' tcx>,
617
+ iter: impl :: std:: iter:: IntoIterator <Item = Self >,
618
+ ) -> & ' a mut [ Self ] ;
622
619
}
623
620
624
- unsafe impl <' tcx, T : ArenaAllocatable < ' tcx>> ArenaField <' tcx> for T {
621
+ impl <' tcx, T : Copy > ArenaAllocatable <' tcx, ( ) > for T {
625
622
#[ inline]
626
- default fn arena<' a>( _: & ' a Arena <' tcx>) -> Option <& ' a $crate:: TypedArena <Self >> {
627
- panic!( )
623
+ fn allocate_on<' a>( self , arena: & ' a Arena <' tcx>) -> & ' a mut Self {
624
+ arena. dropless. alloc( self )
625
+ }
626
+ #[ inline]
627
+ fn allocate_from_iter<' a>(
628
+ arena: & ' a Arena <' tcx>,
629
+ iter: impl :: std:: iter:: IntoIterator <Item = Self >,
630
+ ) -> & ' a mut [ Self ] {
631
+ arena. dropless. alloc_from_iter( iter)
628
632
}
629
- }
630
633
634
+ }
631
635
$(
632
- #[ allow( unused_lifetimes) ]
633
- impl <$tcx> ArenaAllocatable <$tcx> for $ty { }
634
- unsafe impl <$tcx, ' _x, ' _y, ' _z, ' _w> ArenaField <$tcx> for $gen_ty where Self : ArenaAllocatable <$tcx> {
636
+ impl <$tcx> ArenaAllocatable <$tcx, $ty> for $ty {
635
637
#[ inline]
636
- fn arena<' a>( _arena: & ' a Arena <$tcx>) -> Option <& ' a $crate:: TypedArena <Self >> {
637
- // SAFETY: We only implement `ArenaAllocatable<$tcx>` for
638
- // `$ty`, so `$ty` and Self are the same type
639
- unsafe {
640
- :: std:: mem:: transmute:: <
641
- Option <& ' a $crate:: TypedArena <$ty>>,
642
- Option <& ' a $crate:: TypedArena <Self >>,
643
- >(
644
- $crate:: which_arena_for_type!( $a[ & _arena. $name] )
645
- )
638
+ fn allocate_on<' a>( self , arena: & ' a Arena <$tcx>) -> & ' a mut Self {
639
+ if !:: std:: mem:: needs_drop:: <Self >( ) {
640
+ return arena. dropless. alloc( self ) ;
641
+ }
642
+ match $crate:: which_arena_for_type!( $a[ & arena. $name] ) {
643
+ :: std:: option:: Option :: <& $crate:: TypedArena <Self >>:: Some ( ty_arena) => {
644
+ ty_arena. alloc( self )
645
+ }
646
+ :: std:: option:: Option :: None => unsafe { arena. drop. alloc( self ) } ,
647
+ }
648
+ }
649
+
650
+ #[ inline]
651
+ fn allocate_from_iter<' a>(
652
+ arena: & ' a Arena <$tcx>,
653
+ iter: impl :: std:: iter:: IntoIterator <Item = Self >,
654
+ ) -> & ' a mut [ Self ] {
655
+ if !:: std:: mem:: needs_drop:: <Self >( ) {
656
+ return arena. dropless. alloc_from_iter( iter) ;
657
+ }
658
+ match $crate:: which_arena_for_type!( $a[ & arena. $name] ) {
659
+ :: std:: option:: Option :: <& $crate:: TypedArena <Self >>:: Some ( ty_arena) => {
660
+ ty_arena. alloc_from_iter( iter)
661
+ }
662
+ :: std:: option:: Option :: None => unsafe { arena. drop. alloc_from_iter( iter) } ,
646
663
}
647
664
}
648
665
}
649
666
) *
650
667
651
668
impl <' tcx> Arena <' tcx> {
652
669
#[ inline]
653
- pub fn alloc<T : ArenaAllocatable <' tcx>>( & self , value: T ) -> & mut T {
654
- if !:: std:: mem:: needs_drop:: <T >( ) {
655
- return self . dropless. alloc( value) ;
656
- }
657
- match <T as ArenaField <' tcx>>:: arena( self ) {
658
- :: std:: option:: Option :: Some ( arena) => arena. alloc( value) ,
659
- :: std:: option:: Option :: None => unsafe { self . drop. alloc( value) } ,
660
- }
670
+ pub fn alloc<T : ArenaAllocatable <' tcx, U >, U >( & self , value: T ) -> & mut T {
671
+ value. allocate_on( self )
661
672
}
662
673
663
674
#[ inline]
@@ -668,17 +679,11 @@ macro_rules! declare_arena {
668
679
self . dropless. alloc_slice( value)
669
680
}
670
681
671
- pub fn alloc_from_iter<' a, T : ArenaAllocatable <' tcx> >(
682
+ pub fn alloc_from_iter<' a, T : ArenaAllocatable <' tcx, U > , U >(
672
683
& ' a self ,
673
684
iter: impl :: std:: iter:: IntoIterator <Item = T >,
674
685
) -> & ' a mut [ T ] {
675
- if !:: std:: mem:: needs_drop:: <T >( ) {
676
- return self . dropless. alloc_from_iter( iter) ;
677
- }
678
- match <T as ArenaField <' tcx>>:: arena( self ) {
679
- :: std:: option:: Option :: Some ( arena) => arena. alloc_from_iter( iter) ,
680
- :: std:: option:: Option :: None => unsafe { self . drop. alloc_from_iter( iter) } ,
681
- }
686
+ T :: allocate_from_iter( self , iter)
682
687
}
683
688
}
684
689
}
0 commit comments