Skip to content

Commit 86c406f

Browse files
authored
Rollup merge of rust-lang#73378 - matthewjasper:arena-not-special, r=oli-obk
Remove use of specialization from librustc_arena This reworks the macro so that specialization, `transmute` and `#[marker]` are not used. r? @oli-obk
2 parents 85f619d + 1b92d59 commit 86c406f

File tree

3 files changed

+52
-46
lines changed

3 files changed

+52
-46
lines changed

src/librustc_arena/lib.rs

+52-43
Original file line numberDiff line numberDiff line change
@@ -611,62 +611,77 @@ macro_rules! which_arena_for_type {
611611

612612
#[macro_export]
613613
macro_rules! declare_arena {
614-
([], [$($a:tt $name:ident: $ty:ty, $gen_ty:ty;)*], $tcx:lifetime) => {
614+
// This macro has to take the same input as
615+
// `impl_arena_allocatable_decoders` which requires a second version of
616+
// each type. We ignore that type until we can fix
617+
// `impl_arena_allocatable_decoders`.
618+
([], [$($a:tt $name:ident: $ty:ty, $_gen_ty:ty;)*], $tcx:lifetime) => {
615619
#[derive(Default)]
616620
pub struct Arena<$tcx> {
617621
pub dropless: $crate::DroplessArena,
618622
drop: $crate::DropArena,
619623
$($name: $crate::arena_for_type!($a[$ty]),)*
620624
}
621625

622-
#[marker]
623-
pub trait ArenaAllocatable<'tcx> {}
624-
625-
impl<'tcx, T: Copy> ArenaAllocatable<'tcx> for T {}
626-
627-
unsafe trait ArenaField<'tcx>: Sized + ArenaAllocatable<'tcx> {
628-
/// Returns a specific arena to allocate from.
629-
/// If `None` is returned, the `DropArena` will be used.
630-
fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena<Self>>;
626+
pub trait ArenaAllocatable<'tcx, T = Self>: Sized {
627+
fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self;
628+
fn allocate_from_iter<'a>(
629+
arena: &'a Arena<'tcx>,
630+
iter: impl ::std::iter::IntoIterator<Item = Self>,
631+
) -> &'a mut [Self];
631632
}
632633

633-
unsafe impl<'tcx, T: ArenaAllocatable<'tcx>> ArenaField<'tcx> for T {
634+
impl<'tcx, T: Copy> ArenaAllocatable<'tcx, ()> for T {
634635
#[inline]
635-
default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a $crate::TypedArena<Self>> {
636-
panic!()
636+
fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self {
637+
arena.dropless.alloc(self)
638+
}
639+
#[inline]
640+
fn allocate_from_iter<'a>(
641+
arena: &'a Arena<'tcx>,
642+
iter: impl ::std::iter::IntoIterator<Item = Self>,
643+
) -> &'a mut [Self] {
644+
arena.dropless.alloc_from_iter(iter)
637645
}
638-
}
639646

647+
}
640648
$(
641-
#[allow(unused_lifetimes)]
642-
impl<$tcx> ArenaAllocatable<$tcx> for $ty {}
643-
unsafe impl<$tcx, '_x, '_y, '_z, '_w> ArenaField<$tcx> for $gen_ty where Self: ArenaAllocatable<$tcx> {
649+
impl<$tcx> ArenaAllocatable<$tcx, $ty> for $ty {
644650
#[inline]
645-
fn arena<'a>(_arena: &'a Arena<$tcx>) -> Option<&'a $crate::TypedArena<Self>> {
646-
// SAFETY: We only implement `ArenaAllocatable<$tcx>` for
647-
// `$ty`, so `$ty` and Self are the same type
648-
unsafe {
649-
::std::mem::transmute::<
650-
Option<&'a $crate::TypedArena<$ty>>,
651-
Option<&'a $crate::TypedArena<Self>>,
652-
>(
653-
$crate::which_arena_for_type!($a[&_arena.$name])
654-
)
651+
fn allocate_on<'a>(self, arena: &'a Arena<$tcx>) -> &'a mut Self {
652+
if !::std::mem::needs_drop::<Self>() {
653+
return arena.dropless.alloc(self);
654+
}
655+
match $crate::which_arena_for_type!($a[&arena.$name]) {
656+
::std::option::Option::<&$crate::TypedArena<Self>>::Some(ty_arena) => {
657+
ty_arena.alloc(self)
658+
}
659+
::std::option::Option::None => unsafe { arena.drop.alloc(self) },
660+
}
661+
}
662+
663+
#[inline]
664+
fn allocate_from_iter<'a>(
665+
arena: &'a Arena<$tcx>,
666+
iter: impl ::std::iter::IntoIterator<Item = Self>,
667+
) -> &'a mut [Self] {
668+
if !::std::mem::needs_drop::<Self>() {
669+
return arena.dropless.alloc_from_iter(iter);
670+
}
671+
match $crate::which_arena_for_type!($a[&arena.$name]) {
672+
::std::option::Option::<&$crate::TypedArena<Self>>::Some(ty_arena) => {
673+
ty_arena.alloc_from_iter(iter)
674+
}
675+
::std::option::Option::None => unsafe { arena.drop.alloc_from_iter(iter) },
655676
}
656677
}
657678
}
658679
)*
659680

660681
impl<'tcx> Arena<'tcx> {
661682
#[inline]
662-
pub fn alloc<T: ArenaAllocatable<'tcx>>(&self, value: T) -> &mut T {
663-
if !::std::mem::needs_drop::<T>() {
664-
return self.dropless.alloc(value);
665-
}
666-
match <T as ArenaField<'tcx>>::arena(self) {
667-
::std::option::Option::Some(arena) => arena.alloc(value),
668-
::std::option::Option::None => unsafe { self.drop.alloc(value) },
669-
}
683+
pub fn alloc<T: ArenaAllocatable<'tcx, U>, U>(&self, value: T) -> &mut T {
684+
value.allocate_on(self)
670685
}
671686

672687
#[inline]
@@ -677,17 +692,11 @@ macro_rules! declare_arena {
677692
self.dropless.alloc_slice(value)
678693
}
679694

680-
pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx>>(
695+
pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx, U>, U>(
681696
&'a self,
682697
iter: impl ::std::iter::IntoIterator<Item = T>,
683698
) -> &'a mut [T] {
684-
if !::std::mem::needs_drop::<T>() {
685-
return self.dropless.alloc_from_iter(iter);
686-
}
687-
match <T as ArenaField<'tcx>>::arena(self) {
688-
::std::option::Option::Some(arena) => arena.alloc_from_iter(iter),
689-
::std::option::Option::None => unsafe { self.drop.alloc_from_iter(iter) },
690-
}
699+
T::allocate_from_iter(self, iter)
691700
}
692701
}
693702
}

src/librustc_ast_lowering/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
3333
#![feature(array_value_iter)]
3434
#![feature(crate_visibility_modifier)]
35-
#![feature(marker_trait_attr)]
36-
#![feature(min_specialization)]
3735
#![feature(or_patterns)]
3836
#![recursion_limit = "256"]
3937

src/librustc_middle/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
#![feature(drain_filter)]
3737
#![feature(never_type)]
3838
#![feature(exhaustive_patterns)]
39-
#![feature(marker_trait_attr)]
4039
#![feature(extern_types)]
4140
#![feature(nll)]
4241
#![feature(option_expect_none)]

0 commit comments

Comments
 (0)