-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce an arena type which may be used to allocate a list of types with destructors #59536
Changes from 3 commits
002c70f
e835d27
4ccb9ae
43e33ea
04762dd
223f1c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
use arena::{TypedArena, DroplessArena}; | ||
use std::mem; | ||
|
||
#[macro_export] | ||
macro_rules! arena_types { | ||
($macro:path, $args:tt, $tcx:lifetime) => ( | ||
$macro!($args, [ | ||
[] vtable_method: Option<( | ||
rustc::hir::def_id::DefId, | ||
rustc::ty::subst::SubstsRef<$tcx> | ||
)>, | ||
[decode] specialization_graph: rustc::traits::specialization_graph::Graph, | ||
], $tcx); | ||
) | ||
} | ||
|
||
macro_rules! declare_arena { | ||
([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => { | ||
#[derive(Default)] | ||
pub struct Arena<$tcx> { | ||
dropless: DroplessArena, | ||
$($name: TypedArena<$ty>,)* | ||
} | ||
} | ||
} | ||
|
||
macro_rules! impl_arena_allocatable { | ||
([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => { | ||
$( | ||
impl ArenaAllocatable for $ty {} | ||
impl<$tcx> ArenaField<$tcx> for $ty { | ||
#[inline] | ||
fn arena<'a>(arena: &'a Arena<$tcx>) -> &'a TypedArena<Self> { | ||
&arena.$name | ||
} | ||
} | ||
)* | ||
} | ||
} | ||
|
||
arena_types!(declare_arena, [], 'tcx); | ||
|
||
arena_types!(impl_arena_allocatable, [], 'tcx); | ||
|
||
pub trait ArenaAllocatable {} | ||
|
||
impl<T: Copy> ArenaAllocatable for T {} | ||
|
||
pub trait ArenaField<'tcx>: Sized { | ||
/// Returns a specific arena to allocate from. | ||
fn arena<'a>(arena: &'a Arena<'tcx>) -> &'a TypedArena<Self>; | ||
} | ||
|
||
impl<'tcx, T> ArenaField<'tcx> for T { | ||
#[inline] | ||
default fn arena<'a>(_: &'a Arena<'tcx>) -> &'a TypedArena<Self> { | ||
panic!() | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This impl can conflict with the types in the list :(
Do we have some way to express an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh wow, it would be nice to be able to rely on sets and maps never being There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I found a way around this using a marker trait. |
||
} | ||
|
||
impl<'tcx> Arena<'tcx> { | ||
#[inline] | ||
pub fn alloc<T: ArenaAllocatable>(&self, value: T) -> &mut T { | ||
if mem::needs_drop::<T>() { | ||
<T as ArenaField<'tcx>>::arena(self).alloc(value) | ||
} else { | ||
self.dropless.alloc(value) | ||
} | ||
} | ||
|
||
pub fn alloc_from_iter< | ||
T: ArenaAllocatable, | ||
I: IntoIterator<Item = T> | ||
>( | ||
&self, | ||
iter: I | ||
) -> &mut [T] { | ||
if mem::needs_drop::<T>() { | ||
<T as ArenaField<'tcx>>::arena(self).alloc_from_iter(iter) | ||
} else { | ||
self.dropless.alloc_from_iter(iter) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -911,4 +911,5 @@ impl<T: UseSpecializedDecodable> Decodable for T { | |
impl<'a, T: ?Sized + Encodable> UseSpecializedEncodable for &'a T {} | ||
impl<T: ?Sized + Encodable> UseSpecializedEncodable for Box<T> {} | ||
impl<T: Decodable> UseSpecializedDecodable for Box<T> {} | ||
|
||
impl<'a, T: ?Sized + Decodable> UseSpecializedDecodable for &'a T {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I see, |
||
impl<'a, T: ?Sized + Decodable> UseSpecializedDecodable for &'a [T] {} | ||
Zoxc marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The list of types are declared here with a macro.