Skip to content

Commit 5833c19

Browse files
committed
Make ArenaAllocatable a marker trait to allow overlapping impls and use specialization to find the right field
1 parent 7120ef3 commit 5833c19

File tree

3 files changed

+28
-28
lines changed

3 files changed

+28
-28
lines changed

src/librustc/arena.rs

+25-26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use arena::{TypedArena, DroplessArena};
2+
use std::mem;
23

34
#[macro_export]
45
macro_rules! arena_types {
@@ -35,10 +36,11 @@ macro_rules! impl_arena_allocatable {
3536
$(
3637
impl_specialized_decodable!($a $ty, $tcx);
3738

38-
impl<$tcx> ArenaAllocatable<$tcx> for $ty {
39+
impl ArenaAllocatable for $ty {}
40+
impl<$tcx> ArenaField<$tcx> for $ty {
3941
#[inline]
40-
fn arena<'a>(arena: &'a Arena<$tcx>) -> Option<&'a TypedArena<Self>> {
41-
Some(&arena.$name)
42+
fn arena<'a>(arena: &'a Arena<$tcx>) -> &'a TypedArena<Self> {
43+
&arena.$name
4244
}
4345
}
4446
)*
@@ -49,46 +51,43 @@ arena_types!(declare_arena, [], 'tcx);
4951

5052
arena_types!(impl_arena_allocatable, [], 'tcx);
5153

52-
pub trait ArenaAllocatable<'tcx>: Sized {
53-
/// Returns a specific arena to allocate from if the type requires destructors.
54-
/// Otherwise it will return `None` to be allocated from the dropless arena.
55-
fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>>;
54+
pub trait ArenaAllocatable {}
55+
56+
impl<T: Copy> ArenaAllocatable for T {}
57+
58+
pub trait ArenaField<'tcx>: Sized {
59+
/// Returns a specific arena to allocate from.
60+
fn arena<'a>(arena: &'a Arena<'tcx>) -> &'a TypedArena<Self>;
5661
}
5762

58-
impl<'tcx, T: Copy> ArenaAllocatable<'tcx> for T {
63+
impl<'tcx, T> ArenaField<'tcx> for T {
5964
#[inline]
60-
default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>> {
61-
None
65+
default fn arena<'a>(_: &'a Arena<'tcx>) -> &'a TypedArena<Self> {
66+
panic!()
6267
}
6368
}
6469

6570
impl<'tcx> Arena<'tcx> {
6671
#[inline]
67-
pub fn alloc<T: ArenaAllocatable<'tcx>>(&self, value: T) -> &mut T {
68-
match T::arena(self) {
69-
Some(arena) => {
70-
arena.alloc(value)
71-
}
72-
None => {
73-
self.dropless.alloc(value)
74-
}
72+
pub fn alloc<T: ArenaAllocatable>(&self, value: T) -> &mut T {
73+
if mem::needs_drop::<T>() {
74+
<T as ArenaField<'tcx>>::arena(self).alloc(value)
75+
} else {
76+
self.dropless.alloc(value)
7577
}
7678
}
7779

7880
pub fn alloc_from_iter<
79-
T: ArenaAllocatable<'tcx>,
81+
T: ArenaAllocatable,
8082
I: IntoIterator<Item = T>
8183
>(
8284
&self,
8385
iter: I
8486
) -> &mut [T] {
85-
match T::arena(self) {
86-
Some(arena) => {
87-
arena.alloc_from_iter(iter)
88-
}
89-
None => {
90-
self.dropless.alloc_from_iter(iter)
91-
}
87+
if mem::needs_drop::<T>() {
88+
<T as ArenaField<'tcx>>::arena(self).alloc_from_iter(iter)
89+
} else {
90+
self.dropless.alloc_from_iter(iter)
9291
}
9392
}
9493
}

src/librustc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#![cfg_attr(windows, feature(libc))]
4040
#![feature(never_type)]
4141
#![feature(exhaustive_patterns)]
42+
#![feature(overlapping_marker_traits)]
4243
#![feature(extern_types)]
4344
#![feature(nll)]
4445
#![feature(non_exhaustive)]

src/librustc/ty/codec.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ pub trait TyDecoder<'a, 'tcx: 'a>: Decoder {
132132
}
133133

134134
#[inline]
135-
pub fn decode_arena_allocable<'a, 'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>(
135+
pub fn decode_arena_allocable<'a, 'tcx, D, T: ArenaAllocatable + Decodable>(
136136
decoder: &mut D
137137
) -> Result<&'tcx T, D::Error>
138138
where D: TyDecoder<'a, 'tcx>,
@@ -142,7 +142,7 @@ pub fn decode_arena_allocable<'a, 'tcx, D, T: ArenaAllocatable<'tcx> + Decodable
142142
}
143143

144144
#[inline]
145-
pub fn decode_arena_allocable_slice<'a, 'tcx, D, T: ArenaAllocatable<'tcx> + Decodable>(
145+
pub fn decode_arena_allocable_slice<'a, 'tcx, D, T: ArenaAllocatable + Decodable>(
146146
decoder: &mut D
147147
) -> Result<&'tcx [T], D::Error>
148148
where D: TyDecoder<'a, 'tcx>,

0 commit comments

Comments
 (0)