@@ -602,62 +602,73 @@ macro_rules! which_arena_for_type {
602602
603603#[ macro_export]
604604macro_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) => {
606606 #[ derive( Default ) ]
607607 pub struct Arena <$tcx> {
608608 pub dropless: $crate:: DroplessArena ,
609609 drop: $crate:: DropArena ,
610610 $( $name: $crate:: arena_for_type!( $a[ $ty] ) , ) *
611611 }
612612
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 ] ;
622619 }
623620
624- unsafe impl <' tcx, T : ArenaAllocatable < ' tcx>> ArenaField <' tcx> for T {
621+ impl <' tcx, T : Copy > ArenaAllocatable <' tcx, ( ) > for T {
625622 #[ 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)
628632 }
629- }
630633
634+ }
631635 $(
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 {
635637 #[ 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) } ,
646663 }
647664 }
648665 }
649666 ) *
650667
651668 impl <' tcx> Arena <' tcx> {
652669 #[ 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 )
661672 }
662673
663674 #[ inline]
@@ -668,17 +679,11 @@ macro_rules! declare_arena {
668679 self . dropless. alloc_slice( value)
669680 }
670681
671- pub fn alloc_from_iter<' a, T : ArenaAllocatable <' tcx> >(
682+ pub fn alloc_from_iter<' a, T : ArenaAllocatable <' tcx, U > , U >(
672683 & ' a self ,
673684 iter: impl :: std:: iter:: IntoIterator <Item = T >,
674685 ) -> & ' 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)
682687 }
683688 }
684689 }
0 commit comments