11use arena:: { TypedArena , DroplessArena } ;
2+ use std:: mem;
23
34#[ macro_export]
45macro_rules! arena_types {
@@ -35,10 +36,11 @@ macro_rules! impl_arena_allocatable {
3536 $(
3637 impl_specialized_decodable!( $a $ty, $tcx) ;
3738
38- impl <$tcx> ArenaAllocatable <$tcx> for $ty {
39+ impl ArenaAllocatable for $ty { }
40+ impl <$tcx> ArenaField <$tcx> for $ty {
3941 #[ inline]
40- fn arena<' a>( arena: & ' a Arena <$tcx>) -> Option < & ' a TypedArena <Self > > {
41- Some ( & arena. $name)
42+ fn arena<' a>( arena: & ' a Arena <$tcx>) -> & ' a TypedArena <Self > {
43+ & arena. $name
4244 }
4345 }
4446 ) *
@@ -49,46 +51,43 @@ arena_types!(declare_arena, [], 'tcx);
4951
5052arena_types ! ( impl_arena_allocatable, [ ] , ' tcx) ;
5153
52- pub trait ArenaAllocatable < ' tcx > : Sized {
53- /// Returns a specific arena to allocate from if the type requires destructors.
54- /// Otherwise it will return `None` to be allocated from the dropless arena.
55- fn arena < ' a > ( arena : & ' a Arena < ' tcx > ) -> Option < & ' a TypedArena < Self > > ;
54+ pub trait ArenaAllocatable { }
55+
56+ impl < T : Copy > ArenaAllocatable for T { }
57+
58+ pub trait ArenaField < ' tcx > : Sized {
59+ /// Returns a specific arena to allocate from.
60+ fn arena < ' a > ( arena : & ' a Arena < ' tcx > ) -> & ' a TypedArena < Self > ;
5661}
5762
58- impl < ' tcx , T : Copy > ArenaAllocatable < ' tcx > for T {
63+ impl < ' tcx , T > ArenaField < ' tcx > for T {
5964 #[ inline]
60- default fn arena < ' a > ( _: & ' a Arena < ' tcx > ) -> Option < & ' a TypedArena < Self > > {
61- None
65+ default fn arena < ' a > ( _: & ' a Arena < ' tcx > ) -> & ' a TypedArena < Self > {
66+ panic ! ( )
6267 }
6368}
6469
6570impl < ' tcx > Arena < ' tcx > {
6671 #[ inline]
67- pub fn alloc < T : ArenaAllocatable < ' tcx > > ( & self , value : T ) -> & mut T {
68- match T :: arena ( self ) {
69- Some ( arena) => {
70- arena. alloc ( value)
71- }
72- None => {
73- self . dropless . alloc ( value)
74- }
72+ pub fn alloc < T : ArenaAllocatable > ( & self , value : T ) -> & mut T {
73+ if mem:: needs_drop :: < T > ( ) {
74+ <T as ArenaField < ' tcx > >:: arena ( self ) . alloc ( value)
75+ } else {
76+ self . dropless . alloc ( value)
7577 }
7678 }
7779
7880 pub fn alloc_from_iter <
79- T : ArenaAllocatable < ' tcx > ,
81+ T : ArenaAllocatable ,
8082 I : IntoIterator < Item = T >
8183 > (
8284 & self ,
8385 iter : I
8486 ) -> & mut [ T ] {
85- match T :: arena ( self ) {
86- Some ( arena) => {
87- arena. alloc_from_iter ( iter)
88- }
89- None => {
90- self . dropless . alloc_from_iter ( iter)
91- }
87+ if mem:: needs_drop :: < T > ( ) {
88+ <T as ArenaField < ' tcx > >:: arena ( self ) . alloc_from_iter ( iter)
89+ } else {
90+ self . dropless . alloc_from_iter ( iter)
9291 }
9392 }
9493}
0 commit comments