Skip to content

Commit

Permalink
Clarify ArenaAllocatable's second parameter.
Browse files Browse the repository at this point in the history
It's simply a binary thing to allow different behaviour for `Copy` vs
`!Copy` types. The new code makes this much clearer; I was scratching my
head over the old code for some time.
  • Loading branch information
nnethercote committed Jan 27, 2022
1 parent 9065c7c commit 6035487
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions compiler/rustc_arena/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
$($name: $crate::TypedArena<$ty>,)*
}

pub trait ArenaAllocatable<'tcx, T = Self>: Sized {
pub trait ArenaAllocatable<'tcx, C = rustc_arena::IsNotCopy>: Sized {
fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self;
fn allocate_from_iter<'a>(
arena: &'a Arena<'tcx>,
Expand All @@ -555,7 +555,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
}

// Any type that impls `Copy` can be arena-allocated in the `DroplessArena`.
impl<'tcx, T: Copy> ArenaAllocatable<'tcx, ()> for T {
impl<'tcx, T: Copy> ArenaAllocatable<'tcx, rustc_arena::IsCopy> for T {
#[inline]
fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self {
arena.dropless.alloc(self)
Expand All @@ -569,7 +569,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
}
}
$(
impl<'tcx> ArenaAllocatable<'tcx, $ty> for $ty {
impl<'tcx> ArenaAllocatable<'tcx, rustc_arena::IsNotCopy> for $ty {
#[inline]
fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self {
if !::std::mem::needs_drop::<Self>() {
Expand All @@ -595,7 +595,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {

impl<'tcx> Arena<'tcx> {
#[inline]
pub fn alloc<T: ArenaAllocatable<'tcx, U>, U>(&self, value: T) -> &mut T {
pub fn alloc<T: ArenaAllocatable<'tcx, C>, C>(&self, value: T) -> &mut T {
value.allocate_on(self)
}

Expand All @@ -608,7 +608,7 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
self.dropless.alloc_slice(value)
}

pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx, U>, U>(
pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx, C>, C>(
&'a self,
iter: impl ::std::iter::IntoIterator<Item = T>,
) -> &'a mut [T] {
Expand All @@ -617,5 +617,10 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) {
}
}

// Marker types that let us give different behaviour for arenas allocating
// `Copy` types vs `!Copy` types.
pub struct IsCopy;
pub struct IsNotCopy;

#[cfg(test)]
mod tests;

0 comments on commit 6035487

Please sign in to comment.