diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-03-21 01:42:14 +0100 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-03-21 22:18:57 +0100 |
| commit | 4c28d68bc36fb5fc34fda59808b656f17106991d (patch) | |
| tree | 17238842390f2c542a74b795a54bec896a7ceb46 | |
| parent | e60205fe523df786b2c4f7c1fbaf7fa2c053621f (diff) | |
| download | rust-4c28d68bc36fb5fc34fda59808b656f17106991d.tar.gz rust-4c28d68bc36fb5fc34fda59808b656f17106991d.zip | |
move move stuff into declare_arena!
| -rw-r--r-- | src/libarena/lib.rs | 100 | ||||
| -rw-r--r-- | src/librustc/arena.rs | 103 |
2 files changed, 101 insertions, 102 deletions
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 0fb06601914..18200af8b66 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -569,5 +569,105 @@ impl DropArena { } } +#[macro_export] +macro_rules! arena_for_type { + ([][$ty:ty]) => { + $crate::TypedArena<$ty> + }; + ([few $(, $attrs:ident)*][$ty:ty]) => { + ::std::marker::PhantomData<$ty> + }; + ([$ignore:ident $(, $attrs:ident)*]$args:tt) => { + $crate::arena_for_type!([$($attrs),*]$args) + }; +} + +#[macro_export] +macro_rules! which_arena_for_type { + ([][$arena:expr]) => { + ::std::option::Option::Some($arena) + }; + ([few$(, $attrs:ident)*][$arena:expr]) => { + ::std::option::Option::None + }; + ([$ignore:ident$(, $attrs:ident)*]$args:tt) => { + $crate::which_arena_for_type!([$($attrs),*]$args) + }; +} + +#[macro_export] +macro_rules! declare_arena { + ([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => { + #[derive(Default)] + pub struct Arena<$tcx> { + pub dropless: $crate::DroplessArena, + drop: $crate::DropArena, + $($name: $crate::arena_for_type!($a[$ty]),)* + } + + #[marker] + pub trait ArenaAllocatable {} + + impl<T: Copy> ArenaAllocatable for T {} + + unsafe trait ArenaField<'tcx>: Sized { + /// Returns a specific arena to allocate from. + /// If `None` is returned, the `DropArena` will be used. + fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena<Self>>; + } + + unsafe impl<'tcx, T> ArenaField<'tcx> for T { + #[inline] + default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena<Self>> { + panic!() + } + } + + $( + impl ArenaAllocatable for $ty {} + unsafe impl<$tcx> ArenaField<$tcx> for $ty { + #[inline] + fn arena<'a>(_arena: &'a Arena<$tcx>) -> Option<&'a $crate::TypedArena<Self>> { + $crate::which_arena_for_type!($a[&_arena.$name]) + } + } + )* + + impl<'tcx> Arena<'tcx> { + #[inline] + pub fn alloc<T: ArenaAllocatable>(&self, value: T) -> &mut T { + if !::std::mem::needs_drop::<T>() { + return self.dropless.alloc(value); + } + match <T as ArenaField<'tcx>>::arena(self) { + ::std::option::Option::Some(arena) => arena.alloc(value), + ::std::option::Option::None => unsafe { self.drop.alloc(value) }, + } + } + + #[inline] + pub fn alloc_slice<T: ::std::marker::Copy>(&self, value: &[T]) -> &mut [T] { + if value.is_empty() { + return &mut []; + } + self.dropless.alloc_slice(value) + } + + pub fn alloc_from_iter<T: ArenaAllocatable>( + &'a self, + iter: impl ::std::iter::IntoIterator<Item = T>, + ) -> &'a mut [T] { + if !::std::mem::needs_drop::<T>() { + return self.dropless.alloc_from_iter(iter); + } + match <T as ArenaField<'tcx>>::arena(self) { + ::std::option::Option::Some(arena) => arena.alloc_from_iter(iter), + ::std::option::Option::None => unsafe { self.drop.alloc_from_iter(iter) }, + } + } + } + } +} + #[cfg(test)] mod tests; diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index 6805742fe44..5644a65c42b 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -1,7 +1,3 @@ -use arena::{DropArena, DroplessArena, TypedArena}; -use std::marker::PhantomData; -use std::mem; - /// This declares a list of types which can be allocated by `Arena`. /// /// The `few` modifier will cause allocation to use the shared arena and recording the destructor. @@ -167,101 +163,4 @@ macro_rules! arena_types { ) } -macro_rules! arena_for_type { - ([][$ty:ty]) => { - TypedArena<$ty> - }; - ([few $(, $attrs:ident)*][$ty:ty]) => { - PhantomData<$ty> - }; - ([$ignore:ident $(, $attrs:ident)*]$args:tt) => { - arena_for_type!([$($attrs),*]$args) - }; -} - -macro_rules! which_arena_for_type { - ([][$arena:expr]) => { - Some($arena) - }; - ([few$(, $attrs:ident)*][$arena:expr]) => { - None - }; - ([$ignore:ident$(, $attrs:ident)*]$args:tt) => { - which_arena_for_type!([$($attrs),*]$args) - }; -} - -macro_rules! declare_arena { - ([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => { - #[derive(Default)] - pub struct Arena<$tcx> { - pub dropless: DroplessArena, - drop: DropArena, - $($name: arena_for_type!($a[$ty]),)* - } - - #[marker] - pub trait ArenaAllocatable {} - - impl<T: Copy> ArenaAllocatable for T {} - - unsafe trait ArenaField<'tcx>: Sized { - /// Returns a specific arena to allocate from. - /// If `None` is returned, the `DropArena` will be used. - fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>>; - } - - unsafe impl<'tcx, T> ArenaField<'tcx> for T { - #[inline] - default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>> { - panic!() - } - } - - $( - impl ArenaAllocatable for $ty {} - unsafe impl<$tcx> ArenaField<$tcx> for $ty { - #[inline] - fn arena<'a>(_arena: &'a Arena<$tcx>) -> Option<&'a TypedArena<Self>> { - which_arena_for_type!($a[&_arena.$name]) - } - } - )* - - impl<'tcx> Arena<'tcx> { - #[inline] - pub fn alloc<T: ArenaAllocatable>(&self, value: T) -> &mut T { - if !mem::needs_drop::<T>() { - return self.dropless.alloc(value); - } - match <T as ArenaField<'tcx>>::arena(self) { - Some(arena) => arena.alloc(value), - None => unsafe { self.drop.alloc(value) }, - } - } - - #[inline] - pub fn alloc_slice<T: Copy>(&self, value: &[T]) -> &mut [T] { - if value.is_empty() { - return &mut []; - } - self.dropless.alloc_slice(value) - } - - pub fn alloc_from_iter<T: ArenaAllocatable, I: IntoIterator<Item = T>>( - &'a self, - iter: I, - ) -> &'a mut [T] { - if !mem::needs_drop::<T>() { - return self.dropless.alloc_from_iter(iter); - } - match <T as ArenaField<'tcx>>::arena(self) { - Some(arena) => arena.alloc_from_iter(iter), - None => unsafe { self.drop.alloc_from_iter(iter) }, - } - } - } - } -} - -arena_types!(declare_arena, [], 'tcx); +arena_types!(arena::declare_arena, [], 'tcx); |
