@@ -611,62 +611,77 @@ macro_rules! which_arena_for_type {
611611
612612#[ macro_export]
613613macro_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) => {
615619 #[ derive( Default ) ]
616620 pub struct Arena <$tcx> {
617621 pub dropless: $crate:: DroplessArena ,
618622 drop: $crate:: DropArena ,
619623 $( $name: $crate:: arena_for_type!( $a[ $ty] ) , ) *
620624 }
621625
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 ] ;
631632 }
632633
633- unsafe impl <' tcx, T : ArenaAllocatable < ' tcx>> ArenaField <' tcx> for T {
634+ impl <' tcx, T : Copy > ArenaAllocatable <' tcx, ( ) > for T {
634635 #[ 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)
637645 }
638- }
639646
647+ }
640648 $(
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 {
644650 #[ 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) } ,
655676 }
656677 }
657678 }
658679 ) *
659680
660681 impl <' tcx> Arena <' tcx> {
661682 #[ 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 )
670685 }
671686
672687 #[ inline]
@@ -677,17 +692,11 @@ macro_rules! declare_arena {
677692 self . dropless. alloc_slice( value)
678693 }
679694
680- pub fn alloc_from_iter<' a, T : ArenaAllocatable <' tcx> >(
695+ pub fn alloc_from_iter<' a, T : ArenaAllocatable <' tcx, U > , U >(
681696 & ' a self ,
682697 iter: impl :: std:: iter:: IntoIterator <Item = T >,
683698 ) -> & ' 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)
691700 }
692701 }
693702 }
0 commit comments