diff options
| author | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2019-03-30 01:36:51 +0100 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2019-04-05 00:55:07 +0200 |
| commit | e835d27ad3f464bf81e5b702c1412be09761c991 (patch) | |
| tree | 62303ea3b87402dfaed6439056001eead0679b26 | |
| parent | 002c70f2d46e80fcb02ee4214d9a4d4041ee011c (diff) | |
| download | rust-e835d27ad3f464bf81e5b702c1412be09761c991.tar.gz rust-e835d27ad3f464bf81e5b702c1412be09761c991.zip | |
Make ArenaAllocatable a marker trait to allow overlapping impls and use specialization to find the right field
| -rw-r--r-- | src/librustc/arena.rs | 51 | ||||
| -rw-r--r-- | src/librustc/lib.rs | 1 | ||||
| -rw-r--r-- | src/librustc/ty/codec.rs | 4 |
3 files changed, 28 insertions, 28 deletions
diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index 23493d5c93f..1f1060ee243 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -1,4 +1,5 @@ use arena::{TypedArena, DroplessArena}; +use std::mem; #[macro_export] macro_rules! arena_types { @@ -35,10 +36,11 @@ macro_rules! impl_arena_allocatable { $( impl_specialized_decodable!($a $ty, $tcx); - impl<$tcx> ArenaAllocatable<$tcx> for $ty { + impl ArenaAllocatable for $ty {} + impl<$tcx> ArenaField<$tcx> for $ty { #[inline] - fn arena<'a>(arena: &'a Arena<$tcx>) -> Option<&'a TypedArena<Self>> { - Some(&arena.$name) + fn arena<'a>(arena: &'a Arena<$tcx>) -> &'a TypedArena<Self> { + &arena.$name } } )* @@ -49,46 +51,43 @@ arena_types!(declare_arena, [], 'tcx); arena_types!(impl_arena_allocatable, [], 'tcx); -pub trait ArenaAllocatable<'tcx>: Sized { - /// Returns a specific arena to allocate from if the type requires destructors. - /// Otherwise it will return `None` to be allocated from the dropless arena. - fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>>; +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: Copy> ArenaAllocatable<'tcx> for T { +impl<'tcx, T> ArenaField<'tcx> for T { #[inline] - default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>> { - None + default fn arena<'a>(_: &'a Arena<'tcx>) -> &'a TypedArena<Self> { + panic!() } } impl<'tcx> Arena<'tcx> { #[inline] - pub fn alloc<T: ArenaAllocatable<'tcx>>(&self, value: T) -> &mut T { - match T::arena(self) { - Some(arena) => { - arena.alloc(value) - } - None => { - self.dropless.alloc(value) - } + 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<'tcx>, + T: ArenaAllocatable, I: IntoIterator<Item = T> >( &self, iter: I ) -> &mut [T] { - match T::arena(self) { - Some(arena) => { - arena.alloc_from_iter(iter) - } - None => { - self.dropless.alloc_from_iter(iter) - } + if mem::needs_drop::<T>() { + <T as ArenaField<'tcx>>::arena(self).alloc_from_iter(iter) + } else { + self.dropless.alloc_from_iter(iter) } } } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index ab44efa5dec..c5c2cbfcb89 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -40,6 +40,7 @@ #![cfg_attr(windows, feature(libc))] #![feature(never_type)] #![feature(exhaustive_patterns)] +#![feature(overlapping_marker_traits)] #![feature(extern_types)] #![feature(nll)] #![feature(non_exhaustive)] diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index 038cd9812e7..3046d53086c 100644 --- a/src/librustc/ty/codec.rs +++ b/src/librustc/ty/codec.rs @@ -132,7 +132,7 @@ pub trait TyDecoder<'a, 'tcx: 'a>: Decoder { } #[inline] -pub fn decode_arena_allocable<'a, 'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>( +pub fn decode_arena_allocable<'a, 'tcx, D, T: ArenaAllocatable + Decodable>( decoder: &mut D ) -> Result<&'tcx T, D::Error> where D: TyDecoder<'a, 'tcx>, @@ -142,7 +142,7 @@ pub fn decode_arena_allocable<'a, 'tcx, D, T: ArenaAllocatable<'tcx> + Decodable } #[inline] -pub fn decode_arena_allocable_slice<'a, 'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>( +pub fn decode_arena_allocable_slice<'a, 'tcx, D, T: ArenaAllocatable + Decodable>( decoder: &mut D ) -> Result<&'tcx [T], D::Error> where D: TyDecoder<'a, 'tcx>, |
