@@ -2,6 +2,12 @@ use std::{cell::UnsafeCell, marker::PhantomData, num::{NonZeroU32, NonZeroUsize}
22
33const DEFAULT_CAPACITY : usize = 256 ;
44
5+ /// Trait for keys for Arenas.
6+ ///
7+ /// These are the core methods necessary to use a particular opaque type as
8+ /// a key for the various Arena types. However, for the most part you do not need
9+ /// to implement ArenaKey manually. Instead, use [`define_arena_key!`] for defining
10+ /// your opaque key types.
511pub trait ArenaKey : Copy {
612 fn to_nonzero_usize ( self ) -> NonZeroUsize ;
713 unsafe fn from_nonzero_u32 ( id : NonZeroU32 ) -> Self ;
@@ -13,30 +19,44 @@ pub trait ArenaKey: Copy {
1319
1420 #[ inline( always) ]
1521 unsafe fn from_index ( index : usize ) -> Self {
16- #[ cfg( debug_assertions) ]
17- {
18- Self :: from_nonzero_u32 ( NonZeroU32 :: new ( index as u32 + 1 ) . unwrap ( ) )
19- }
22+ unsafe {
23+ #[ cfg( debug_assertions) ]
24+ {
25+ Self :: from_nonzero_u32 ( NonZeroU32 :: new ( index as u32 + 1 ) . unwrap ( ) )
26+ }
2027
21- #[ cfg( not( debug_assertions) ) ]
22- {
23- Self :: from_nonzero_u32 ( NonZeroU32 :: new_unchecked ( index as u32 + 1 ) )
28+ #[ cfg( not( debug_assertions) ) ]
29+ {
30+ Self :: from_nonzero_u32 ( NonZeroU32 :: new_unchecked ( index as u32 + 1 ) )
31+ }
2432 }
2533 }
2634
2735 #[ inline( always) ]
2836 unsafe fn invalid ( ) -> Self {
29- Self :: from_index ( 0 )
37+ unsafe { Self :: from_index ( 0 ) }
3038 }
3139}
3240
41+ /// Defines a new key type for an Arena.
42+ ///
43+ /// The idea here is to associate a new opaque type with each kind of Arena.
44+ /// For example, if you have an Arena of Exprs and an Arena of Stmts, you may
45+ /// want an ExprKey/ExprId and a StmtKey/StmtId.
46+ ///
47+ /// In this case, you could `define_arena_key!(ExprId);` and then later construct
48+ /// a new arena such as `let arena: Arena<Expr, ExprId> = ...;`
49+ ///
50+ /// Note that Arena keys are currently not associated in any way with the Arena
51+ /// instance they belong to. This may change in the future.
52+ #[ macro_export]
3353macro_rules! define_arena_key {
3454 ( $key_name: ident) => {
3555 #[ derive( Clone , Copy , PartialEq , Eq , Hash ) ]
3656 pub struct $key_name( std:: num:: NonZeroU32 ) ;
3757
3858 // TODO: Is this the best fully qualified name for this trait?
39- impl crate :: arena :: ArenaKey for $key_name {
59+ impl $ crate:: ArenaKey for $key_name {
4060 #[ inline( always) ]
4161 fn to_nonzero_usize( self ) -> std:: num:: NonZeroUsize {
4262 // Safety: Our self.0 is always nonzero, so this should always also
@@ -52,6 +72,11 @@ macro_rules! define_arena_key {
5272 }
5373}
5474
75+ /// The simplest Arena type.
76+ ///
77+ /// This Arena is essentially a `Vec<Ty>`, indexed by the `Key` type. The main
78+ /// value it provides is to enable the Key types to be opaque, rather than
79+ /// normal `usize`s, and to enable conversion into an ArenaCell.
5580pub struct Arena < Ty , Key : ArenaKey > {
5681 objects : Vec < Ty > ,
5782 phantom : PhantomData < Key >
@@ -137,6 +162,21 @@ impl<Ty, Key: ArenaKey> Arena<Ty, Key> {
137162 }
138163}
139164
165+ /// This type is essentially a Vec<RefCell<T>>, except that the borrow checking
166+ /// for the inner T happens entirely in a side table, rather than per-item.
167+ ///
168+ /// There is also an additional caveat that, as of this writing, ArenaCell
169+ /// is *intentionally* unsound. In particular, the runtime borrow-checking rules
170+ /// (a la RefCell) are only enabled when `debug_assertions` are enabled. In
171+ /// release mode, the borrow checking rules are entirely elided.
172+ ///
173+ /// The motivation for this is that the target use-case of ArenaCell, namely
174+ /// compiler data structures, does not really enable 'accidentally' forgetting
175+ /// to drop a borrow. If you have a half-decent test suite, and you have an
176+ /// accidental double-borrow, you WILL see the panic in debug mode, and you
177+ /// will be able to trivially fix it.
178+ ///
179+ /// In the future, there may be some
140180pub struct ArenaCell < Ty , Key : ArenaKey > {
141181 objects : UnsafeCell < Vec < Ty > > ,
142182
0 commit comments