1010
1111use super :: * ;
1212
13- struct OnceCell < T > ( core:: cell:: Cell < Option < T > > ) ;
14- impl < T > OnceCell < T > {
15- pub fn new ( ) -> Self {
16- Self ( core:: cell:: Cell :: new ( None ) )
17- }
18- pub fn set ( & self , x : T ) -> Result < ( ) , ( ) > {
19- // SAFETY: Function is not reentrant so we have exclusive access to the inner data
20- unsafe {
21- let vacant = ( * self . 0 . as_ptr ( ) ) . is_none ( ) ;
22- if vacant {
23- self . 0 . as_ptr ( ) . write ( Some ( x) ) ;
24- Ok ( ( ) )
25- } else {
26- Err ( ( ) )
27- }
28- }
29- }
30- #[ inline]
31- pub fn get ( & self ) -> Option < & T > {
32- // SAFETY: We ensure that we never insert twice (so the inner `T` always lives as long as us, if it exists) and
33- // neither function is possibly reentrant so there's no way we can invalidate mut xor shared aliasing
34- unsafe { ( * self . 0 . as_ptr ( ) ) . as_ref ( ) }
35- }
36- }
37-
3813// TODO: Ensure that this doesn't produce leaks
3914enum RecursiveInner < T : ?Sized > {
4015 Owned ( Arc < T > ) ,
@@ -48,7 +23,7 @@ pub type Direct<'src, 'b, I, O, Extra> = DynParser<'src, 'b, I, O, Extra>;
4823/// Type for recursive parsers that are defined through a call to [`Recursive::declare`], and as
4924/// such require an additional layer of allocation.
5025pub struct Indirect < ' src , ' b , I : Input < ' src > , O , Extra : ParserExtra < ' src , I > > {
51- inner : OnceCell < Box < DynParser < ' src , ' b , I , O , Extra > > > ,
26+ inner : spin :: Once < Box < DynParser < ' src , ' b , I , O , Extra > > > ,
5227}
5328
5429/// A parser that can be defined in terms of itself by separating its [declaration](Recursive::declare) from its
@@ -101,22 +76,14 @@ impl<'src, 'b, I: Input<'src>, O, E: ParserExtra<'src, I>> Recursive<Indirect<'s
10176 pub fn declare ( ) -> Self {
10277 Recursive {
10378 inner : RecursiveInner :: Owned ( Arc :: new ( Indirect {
104- inner : OnceCell :: new ( ) ,
79+ inner : spin :: Once :: new ( ) ,
10580 } ) ) ,
10681 }
10782 }
10883
10984 /// Defines the parser after declaring it, allowing it to be used for parsing.
110- // INFO: Clone bound not actually needed, but good to be safe for future compat
111- #[ track_caller]
112- pub fn define < P : Parser < ' src , I , O , E > + Clone + Send + Sync + ' b > ( & mut self , parser : P ) {
113- let location = * Location :: caller ( ) ;
114- self . parser ( )
115- . inner
116- . set ( Box :: new ( parser) )
117- . unwrap_or_else ( |_| {
118- panic ! ( "recursive parsers can only be defined once, trying to redefine it at {location}" )
119- } ) ;
85+ pub fn define < P : Parser < ' src , I , O , E > + Send + Sync + ' b > ( & mut self , parser : P ) {
86+ self . parser ( ) . inner . call_once ( || Box :: new ( parser) ) ;
12087 }
12188}
12289
@@ -243,7 +210,7 @@ pub fn recursive<'src, 'b, I, O, E, A, F>(f: F) -> Recursive<Direct<'src, 'b, I,
243210where
244211 I : Input < ' src > ,
245212 E : ParserExtra < ' src , I > ,
246- A : Parser < ' src , I , O , E > + Clone + Send + Sync + ' b ,
213+ A : Parser < ' src , I , O , E > + Send + Sync + ' b ,
247214 F : FnOnce ( Recursive < Direct < ' src , ' b , I , O , E > > ) -> A ,
248215{
249216 let rc = Arc :: new_cyclic ( |rc| {
0 commit comments