From 6035487715a528cba30ff4dc0bb9c632e3d24db3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 26 Jan 2022 10:46:40 +1100 Subject: [PATCH] Clarify `ArenaAllocatable`'s second parameter. 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. --- compiler/rustc_arena/src/lib.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index d36e357f58f..3928d70c0ed 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -546,7 +546,7 @@ pub struct Arena<'tcx> { $($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>, @@ -555,7 +555,7 @@ fn allocate_from_iter<'a>( } // 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) @@ -569,7 +569,7 @@ fn allocate_from_iter<'a>( } } $( - 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::() { @@ -595,7 +595,7 @@ fn allocate_from_iter<'a>( impl<'tcx> Arena<'tcx> { #[inline] - pub fn alloc, U>(&self, value: T) -> &mut T { + pub fn alloc, C>(&self, value: T) -> &mut T { value.allocate_on(self) } @@ -608,7 +608,7 @@ pub fn alloc_slice(&self, value: &[T]) -> &mut [T] { 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, ) -> &'a mut [T] { @@ -617,5 +617,10 @@ pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx, U>, U>( } } +// 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;