1
1
use arena:: { TypedArena , DroplessArena } ;
2
+ use std:: mem;
2
3
3
4
#[ macro_export]
4
5
macro_rules! arena_types {
@@ -39,10 +40,11 @@ macro_rules! impl_arena_allocatable {
39
40
$(
40
41
impl_specialized_decodable!( $a $ty, $tcx) ;
41
42
42
- impl <$tcx> ArenaAllocatable <$tcx> for $ty {
43
+ impl ArenaAllocatable for $ty { }
44
+ impl <$tcx> ArenaField <$tcx> for $ty {
43
45
#[ 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
46
48
}
47
49
}
48
50
) *
@@ -53,46 +55,43 @@ arena_types!(declare_arena, [], 'tcx);
53
55
54
56
arena_types ! ( impl_arena_allocatable, [ ] , ' tcx) ;
55
57
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 > ;
60
65
}
61
66
62
- impl < ' tcx , T : Copy > ArenaAllocatable < ' tcx > for T {
67
+ impl < ' tcx , T > ArenaField < ' tcx > for T {
63
68
#[ 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 ! ( )
66
71
}
67
72
}
68
73
69
74
impl < ' tcx > Arena < ' tcx > {
70
75
#[ 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)
79
81
}
80
82
}
81
83
82
84
pub fn alloc_from_iter <
83
- T : ArenaAllocatable < ' tcx > ,
85
+ T : ArenaAllocatable ,
84
86
I : IntoIterator < Item = T >
85
87
> (
86
88
& self ,
87
89
iter : I
88
90
) -> & 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)
96
95
}
97
96
}
98
97
}
0 commit comments