Skip to content

Commit 5e4b0e8

Browse files
committed
Make ArenaAllocatable a marker trait to allow overlapping impls and use specialization to find the right field
1 parent dd59978 commit 5e4b0e8

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 {
@@ -39,10 +40,11 @@ macro_rules! impl_arena_allocatable {
3940
$(
4041
impl_specialized_decodable!($a $ty, $tcx);
4142

42-
impl<$tcx> ArenaAllocatable<$tcx> for $ty {
43+
impl ArenaAllocatable for $ty {}
44+
impl<$tcx> ArenaField<$tcx> for $ty {
4345
#[inline]
44-
fn arena<'a>(arena: &'a Arena<$tcx>) -> Option<&'a TypedArena<Self>> {
45-
Some(&arena.$name)
46+
fn arena<'a>(arena: &'a Arena<$tcx>) -> &'a TypedArena<Self> {
47+
&arena.$name
4648
}
4749
}
4850
)*
@@ -53,46 +55,43 @@ arena_types!(declare_arena, [], 'tcx);
5355

5456
arena_types!(impl_arena_allocatable, [], 'tcx);
5557

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

62-
impl<'tcx, T: Copy> ArenaAllocatable<'tcx> for T {
67+
impl<'tcx, T> ArenaField<'tcx> for T {
6368
#[inline]
64-
default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>> {
65-
None
69+
default fn arena<'a>(_: &'a Arena<'tcx>) -> &'a TypedArena<Self> {
70+
panic!()
6671
}
6772
}
6873

6974
impl<'tcx> Arena<'tcx> {
7075
#[inline]
71-
pub fn alloc<T: ArenaAllocatable<'tcx>>(&self, value: T) -> &mut T {
72-
match T::arena(self) {
73-
Some(arena) => {
74-
arena.alloc(value)
75-
}
76-
None => {
77-
self.dropless.alloc(value)
78-
}
76+
pub fn alloc<T: ArenaAllocatable>(&self, value: T) -> &mut T {
77+
if mem::needs_drop::<T>() {
78+
<T as ArenaField<'tcx>>::arena(self).alloc(value)
79+
} else {
80+
self.dropless.alloc(value)
7981
}
8082
}
8183

8284
pub fn alloc_from_iter<
83-
T: ArenaAllocatable<'tcx>,
85+
T: ArenaAllocatable,
8486
I: IntoIterator<Item = T>
8587
>(
8688
&self,
8789
iter: I
8890
) -> &mut [T] {
89-
match T::arena(self) {
90-
Some(arena) => {
91-
arena.alloc_from_iter(iter)
92-
}
93-
None => {
94-
self.dropless.alloc_from_iter(iter)
95-
}
91+
if mem::needs_drop::<T>() {
92+
<T as ArenaField<'tcx>>::arena(self).alloc_from_iter(iter)
93+
} else {
94+
self.dropless.alloc_from_iter(iter)
9695
}
9796
}
9897
}

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)