11use arena:: { TypedArena , DroplessArena } ;
2+ use std:: mem;
23
34#[ macro_export]
45macro_rules! arena_types {
@@ -39,10 +40,11 @@ macro_rules! impl_arena_allocatable {
3940 $(
4041 impl_specialized_decodable!( $a $ty, $tcx) ;
4142
42- impl <$tcx> ArenaAllocatable <$tcx> for $ty {
43+ impl ArenaAllocatable for $ty { }
44+ impl <$tcx> ArenaField <$tcx> for $ty {
4345 #[ inline]
44- fn arena<' a>( arena: & ' a Arena <$tcx>) -> Option < & ' a TypedArena <Self > > {
45- Some ( & arena. $name)
46+ fn arena<' a>( arena: & ' a Arena <$tcx>) -> & ' a TypedArena <Self > {
47+ & arena. $name
4648 }
4749 }
4850 ) *
@@ -53,46 +55,43 @@ arena_types!(declare_arena, [], 'tcx);
5355
5456arena_types ! ( impl_arena_allocatable, [ ] , ' tcx) ;
5557
56- pub trait ArenaAllocatable < ' tcx > : Sized {
57- /// Returns a specific arena to allocate from if the type requires destructors.
58- /// Otherwise it will return `None` to be allocated from the dropless arena.
59- fn arena < ' a > ( arena : & ' a Arena < ' tcx > ) -> Option < & ' a TypedArena < Self > > ;
58+ pub trait ArenaAllocatable { }
59+
60+ impl < T : Copy > ArenaAllocatable for T { }
61+
62+ pub trait ArenaField < ' tcx > : Sized {
63+ /// Returns a specific arena to allocate from.
64+ fn arena < ' a > ( arena : & ' a Arena < ' tcx > ) -> & ' a TypedArena < Self > ;
6065}
6166
62- impl < ' tcx , T : Copy > ArenaAllocatable < ' tcx > for T {
67+ impl < ' tcx , T > ArenaField < ' tcx > for T {
6368 #[ inline]
64- default fn arena < ' a > ( _: & ' a Arena < ' tcx > ) -> Option < & ' a TypedArena < Self > > {
65- None
69+ default fn arena < ' a > ( _: & ' a Arena < ' tcx > ) -> & ' a TypedArena < Self > {
70+ panic ! ( )
6671 }
6772}
6873
6974impl < ' tcx > Arena < ' tcx > {
7075 #[ inline]
71- pub fn alloc < T : ArenaAllocatable < ' tcx > > ( & self , value : T ) -> & mut T {
72- match T :: arena ( self ) {
73- Some ( arena) => {
74- arena. alloc ( value)
75- }
76- None => {
77- self . dropless . alloc ( value)
78- }
76+ pub fn alloc < T : ArenaAllocatable > ( & self , value : T ) -> & mut T {
77+ if mem:: needs_drop :: < T > ( ) {
78+ <T as ArenaField < ' tcx > >:: arena ( self ) . alloc ( value)
79+ } else {
80+ self . dropless . alloc ( value)
7981 }
8082 }
8183
8284 pub fn alloc_from_iter <
83- T : ArenaAllocatable < ' tcx > ,
85+ T : ArenaAllocatable ,
8486 I : IntoIterator < Item = T >
8587 > (
8688 & self ,
8789 iter : I
8890 ) -> & mut [ T ] {
89- match T :: arena ( self ) {
90- Some ( arena) => {
91- arena. alloc_from_iter ( iter)
92- }
93- None => {
94- self . dropless . alloc_from_iter ( iter)
95- }
91+ if mem:: needs_drop :: < T > ( ) {
92+ <T as ArenaField < ' tcx > >:: arena ( self ) . alloc_from_iter ( iter)
93+ } else {
94+ self . dropless . alloc_from_iter ( iter)
9695 }
9796 }
9897}
0 commit comments