1
1
use arena:: { TypedArena , DroplessArena } ;
2
+ use std:: mem;
2
3
3
4
#[ macro_export]
4
5
macro_rules! arena_types {
@@ -35,10 +36,11 @@ macro_rules! impl_arena_allocatable {
35
36
$(
36
37
impl_specialized_decodable!( $a $ty, $tcx) ;
37
38
38
- impl <$tcx> ArenaAllocatable <$tcx> for $ty {
39
+ impl ArenaAllocatable for $ty { }
40
+ impl <$tcx> ArenaField <$tcx> for $ty {
39
41
#[ 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
42
44
}
43
45
}
44
46
) *
@@ -49,46 +51,43 @@ arena_types!(declare_arena, [], 'tcx);
49
51
50
52
arena_types ! ( impl_arena_allocatable, [ ] , ' tcx) ;
51
53
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 > ;
56
61
}
57
62
58
- impl < ' tcx , T : Copy > ArenaAllocatable < ' tcx > for T {
63
+ impl < ' tcx , T > ArenaField < ' tcx > for T {
59
64
#[ 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 ! ( )
62
67
}
63
68
}
64
69
65
70
impl < ' tcx > Arena < ' tcx > {
66
71
#[ 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)
75
77
}
76
78
}
77
79
78
80
pub fn alloc_from_iter <
79
- T : ArenaAllocatable < ' tcx > ,
81
+ T : ArenaAllocatable ,
80
82
I : IntoIterator < Item = T >
81
83
> (
82
84
& self ,
83
85
iter : I
84
86
) -> & 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)
92
91
}
93
92
}
94
93
}
0 commit comments