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