|
15 | 15 | #![feature(new_uninit)] |
16 | 16 | #![feature(maybe_uninit_slice)] |
17 | 17 | #![feature(min_specialization)] |
| 18 | +#![feature(decl_macro)] |
| 19 | +#![feature(rustc_attrs)] |
18 | 20 | #![cfg_attr(test, feature(test))] |
19 | 21 |
|
20 | 22 | use rustc_data_structures::sync; |
@@ -608,117 +610,113 @@ impl DropArena { |
608 | 610 | } |
609 | 611 | } |
610 | 612 |
|
611 | | -#[macro_export] |
612 | | -macro_rules! arena_for_type { |
| 613 | +pub macro arena_for_type { |
613 | 614 | ([][$ty:ty]) => { |
614 | 615 | $crate::TypedArena<$ty> |
615 | | - }; |
| 616 | + }, |
616 | 617 | ([few $(, $attrs:ident)*][$ty:ty]) => { |
617 | 618 | ::std::marker::PhantomData<$ty> |
618 | | - }; |
| 619 | + }, |
619 | 620 | ([$ignore:ident $(, $attrs:ident)*]$args:tt) => { |
620 | 621 | $crate::arena_for_type!([$($attrs),*]$args) |
621 | | - }; |
| 622 | + }, |
622 | 623 | } |
623 | 624 |
|
624 | | -#[macro_export] |
625 | | -macro_rules! which_arena_for_type { |
| 625 | +pub macro which_arena_for_type { |
626 | 626 | ([][$arena:expr]) => { |
627 | 627 | ::std::option::Option::Some($arena) |
628 | | - }; |
| 628 | + }, |
629 | 629 | ([few$(, $attrs:ident)*][$arena:expr]) => { |
630 | 630 | ::std::option::Option::None |
631 | | - }; |
| 631 | + }, |
632 | 632 | ([$ignore:ident$(, $attrs:ident)*]$args:tt) => { |
633 | 633 | $crate::which_arena_for_type!([$($attrs),*]$args) |
634 | | - }; |
| 634 | + }, |
635 | 635 | } |
636 | 636 |
|
637 | | -#[macro_export] |
638 | | -macro_rules! declare_arena { |
639 | | - ([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => { |
640 | | - #[derive(Default)] |
641 | | - pub struct Arena<$tcx> { |
642 | | - pub dropless: $crate::DroplessArena, |
643 | | - drop: $crate::DropArena, |
644 | | - $($name: $crate::arena_for_type!($a[$ty]),)* |
645 | | - } |
| 637 | +#[rustc_macro_transparency = "semitransparent"] |
| 638 | +pub macro declare_arena([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) { |
| 639 | + #[derive(Default)] |
| 640 | + pub struct Arena<$tcx> { |
| 641 | + pub dropless: $crate::DroplessArena, |
| 642 | + drop: $crate::DropArena, |
| 643 | + $($name: $crate::arena_for_type!($a[$ty]),)* |
| 644 | + } |
646 | 645 |
|
647 | | - pub trait ArenaAllocatable<'tcx, T = Self>: Sized { |
648 | | - fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self; |
649 | | - fn allocate_from_iter<'a>( |
650 | | - arena: &'a Arena<'tcx>, |
651 | | - iter: impl ::std::iter::IntoIterator<Item = Self>, |
652 | | - ) -> &'a mut [Self]; |
| 646 | + pub trait ArenaAllocatable<'tcx, T = Self>: Sized { |
| 647 | + fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self; |
| 648 | + fn allocate_from_iter<'a>( |
| 649 | + arena: &'a Arena<'tcx>, |
| 650 | + iter: impl ::std::iter::IntoIterator<Item = Self>, |
| 651 | + ) -> &'a mut [Self]; |
| 652 | + } |
| 653 | + |
| 654 | + impl<'tcx, T: Copy> ArenaAllocatable<'tcx, ()> for T { |
| 655 | + #[inline] |
| 656 | + fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self { |
| 657 | + arena.dropless.alloc(self) |
| 658 | + } |
| 659 | + #[inline] |
| 660 | + fn allocate_from_iter<'a>( |
| 661 | + arena: &'a Arena<'tcx>, |
| 662 | + iter: impl ::std::iter::IntoIterator<Item = Self>, |
| 663 | + ) -> &'a mut [Self] { |
| 664 | + arena.dropless.alloc_from_iter(iter) |
653 | 665 | } |
654 | 666 |
|
655 | | - impl<'tcx, T: Copy> ArenaAllocatable<'tcx, ()> for T { |
| 667 | + } |
| 668 | + $( |
| 669 | + impl<$tcx> ArenaAllocatable<$tcx, $ty> for $ty { |
656 | 670 | #[inline] |
657 | | - fn allocate_on<'a>(self, arena: &'a Arena<'tcx>) -> &'a mut Self { |
658 | | - arena.dropless.alloc(self) |
| 671 | + fn allocate_on<'a>(self, arena: &'a Arena<$tcx>) -> &'a mut Self { |
| 672 | + if !::std::mem::needs_drop::<Self>() { |
| 673 | + return arena.dropless.alloc(self); |
| 674 | + } |
| 675 | + match $crate::which_arena_for_type!($a[&arena.$name]) { |
| 676 | + ::std::option::Option::<&$crate::TypedArena<Self>>::Some(ty_arena) => { |
| 677 | + ty_arena.alloc(self) |
| 678 | + } |
| 679 | + ::std::option::Option::None => unsafe { arena.drop.alloc(self) }, |
| 680 | + } |
659 | 681 | } |
| 682 | + |
660 | 683 | #[inline] |
661 | 684 | fn allocate_from_iter<'a>( |
662 | | - arena: &'a Arena<'tcx>, |
| 685 | + arena: &'a Arena<$tcx>, |
663 | 686 | iter: impl ::std::iter::IntoIterator<Item = Self>, |
664 | 687 | ) -> &'a mut [Self] { |
665 | | - arena.dropless.alloc_from_iter(iter) |
666 | | - } |
667 | | - |
668 | | - } |
669 | | - $( |
670 | | - impl<$tcx> ArenaAllocatable<$tcx, $ty> for $ty { |
671 | | - #[inline] |
672 | | - fn allocate_on<'a>(self, arena: &'a Arena<$tcx>) -> &'a mut Self { |
673 | | - if !::std::mem::needs_drop::<Self>() { |
674 | | - return arena.dropless.alloc(self); |
675 | | - } |
676 | | - match $crate::which_arena_for_type!($a[&arena.$name]) { |
677 | | - ::std::option::Option::<&$crate::TypedArena<Self>>::Some(ty_arena) => { |
678 | | - ty_arena.alloc(self) |
679 | | - } |
680 | | - ::std::option::Option::None => unsafe { arena.drop.alloc(self) }, |
681 | | - } |
| 688 | + if !::std::mem::needs_drop::<Self>() { |
| 689 | + return arena.dropless.alloc_from_iter(iter); |
682 | 690 | } |
683 | | - |
684 | | - #[inline] |
685 | | - fn allocate_from_iter<'a>( |
686 | | - arena: &'a Arena<$tcx>, |
687 | | - iter: impl ::std::iter::IntoIterator<Item = Self>, |
688 | | - ) -> &'a mut [Self] { |
689 | | - if !::std::mem::needs_drop::<Self>() { |
690 | | - return arena.dropless.alloc_from_iter(iter); |
691 | | - } |
692 | | - match $crate::which_arena_for_type!($a[&arena.$name]) { |
693 | | - ::std::option::Option::<&$crate::TypedArena<Self>>::Some(ty_arena) => { |
694 | | - ty_arena.alloc_from_iter(iter) |
695 | | - } |
696 | | - ::std::option::Option::None => unsafe { arena.drop.alloc_from_iter(iter) }, |
| 691 | + match $crate::which_arena_for_type!($a[&arena.$name]) { |
| 692 | + ::std::option::Option::<&$crate::TypedArena<Self>>::Some(ty_arena) => { |
| 693 | + ty_arena.alloc_from_iter(iter) |
697 | 694 | } |
| 695 | + ::std::option::Option::None => unsafe { arena.drop.alloc_from_iter(iter) }, |
698 | 696 | } |
699 | 697 | } |
700 | | - )* |
| 698 | + } |
| 699 | + )* |
701 | 700 |
|
702 | | - impl<'tcx> Arena<'tcx> { |
703 | | - #[inline] |
704 | | - pub fn alloc<T: ArenaAllocatable<'tcx, U>, U>(&self, value: T) -> &mut T { |
705 | | - value.allocate_on(self) |
706 | | - } |
| 701 | + impl<'tcx> Arena<'tcx> { |
| 702 | + #[inline] |
| 703 | + pub fn alloc<T: ArenaAllocatable<'tcx, U>, U>(&self, value: T) -> &mut T { |
| 704 | + value.allocate_on(self) |
| 705 | + } |
707 | 706 |
|
708 | | - #[inline] |
709 | | - pub fn alloc_slice<T: ::std::marker::Copy>(&self, value: &[T]) -> &mut [T] { |
710 | | - if value.is_empty() { |
711 | | - return &mut []; |
712 | | - } |
713 | | - self.dropless.alloc_slice(value) |
| 707 | + #[inline] |
| 708 | + pub fn alloc_slice<T: ::std::marker::Copy>(&self, value: &[T]) -> &mut [T] { |
| 709 | + if value.is_empty() { |
| 710 | + return &mut []; |
714 | 711 | } |
| 712 | + self.dropless.alloc_slice(value) |
| 713 | + } |
715 | 714 |
|
716 | | - pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx, U>, U>( |
717 | | - &'a self, |
718 | | - iter: impl ::std::iter::IntoIterator<Item = T>, |
719 | | - ) -> &'a mut [T] { |
720 | | - T::allocate_from_iter(self, iter) |
721 | | - } |
| 715 | + pub fn alloc_from_iter<'a, T: ArenaAllocatable<'tcx, U>, U>( |
| 716 | + &'a self, |
| 717 | + iter: impl ::std::iter::IntoIterator<Item = T>, |
| 718 | + ) -> &'a mut [T] { |
| 719 | + T::allocate_from_iter(self, iter) |
722 | 720 | } |
723 | 721 | } |
724 | 722 | } |
|
0 commit comments