1010
1111use super :: * ;
1212
13+ mod private {
14+ pub trait RecursiveState { }
15+ }
16+
17+ use private:: RecursiveState ;
18+
19+ /// A State which represents when a [`Recursive`](Recursive) has been declared, but not defined
20+ pub struct Declared ;
21+
22+ /// A State which represents when a [`Recursive`](Recursive) has been both defined and declared
23+ pub struct Defined ;
24+
25+ impl RecursiveState for Declared { }
26+ impl RecursiveState for Defined { }
27+
1328#[ cfg( not( feature = "sync" ) ) ]
1429struct OnceCell < T > ( core:: cell:: Cell < Option < T > > ) ;
1530#[ cfg( not( feature = "sync" ) ) ]
@@ -80,11 +95,15 @@ pub struct Indirect<'a, 'b, I: Input<'a>, O, Extra: ParserExtra<'a, I>> {
8095/// [definition](Recursive::define).
8196///
8297/// Prefer to use [`recursive()`], which exists as a convenient wrapper around both operations, if possible.
83- pub struct Recursive < P : ?Sized > {
98+ pub struct Recursive < P : ?Sized , S : RecursiveState > {
8499 inner : RecursiveInner < P > ,
100+ #[ allow( dead_code) ]
101+ state : EmptyPhantom < S > ,
85102}
86103
87- impl < ' a , ' b , I : Input < ' a > , O , E : ParserExtra < ' a , I > > Recursive < Indirect < ' a , ' b , I , O , E > > {
104+ impl < ' a , ' b , I : Input < ' a > , O , E : ParserExtra < ' a , I > >
105+ Recursive < Indirect < ' a , ' b , I , O , E > , Declared >
106+ {
88107 /// Declare the existence of a recursive parser, allowing it to be used to construct parser combinators before
89108 /// being fulled defined.
90109 ///
@@ -111,11 +130,11 @@ impl<'a, 'b, I: Input<'a>, O, E: ParserExtra<'a, I>> Recursive<Indirect<'a, 'b,
111130 ///
112131 /// // Define the parser in terms of itself.
113132 /// // In this case, the parser parses a right-recursive list of '+' into a singly linked list
114- /// chain. define(just::<_, _, extra::Err<Simple<char>>>('+')
133+ /// let chain = Recursive:: define(just::<_, _, extra::Err<Simple<char>>>('+')
115134 /// .then(chain.clone())
116135 /// .map(|(c, chain)| Chain::Link(c, Box::new(chain)))
117136 /// .or_not()
118- /// .map(|chain| chain.unwrap_or(Chain::End)));
137+ /// .map(|chain| chain.unwrap_or(Chain::End)), chain );
119138 ///
120139 /// assert_eq!(chain.parse("").into_result(), Ok(Chain::End));
121140 /// assert_eq!(
@@ -128,24 +147,36 @@ impl<'a, 'b, I: Input<'a>, O, E: ParserExtra<'a, I>> Recursive<Indirect<'a, 'b,
128147 inner : RecursiveInner :: Owned ( RefC :: new ( Indirect {
129148 inner : OnceCell :: new ( ) ,
130149 } ) ) ,
150+ state : EmptyPhantom :: new ( ) ,
131151 }
132152 }
133153
134154 /// Defines the parser after declaring it, allowing it to be used for parsing.
135155 // INFO: Clone bound not actually needed, but good to be safe for future compat
136156 #[ track_caller]
137- pub fn define < P : Parser < ' a , I , O , E > + Clone + MaybeSync + ' a + ' b > ( & mut self , parser : P ) {
157+ pub fn define < P : Parser < ' a , I , O , E > + Clone + MaybeSync + ' a + ' b > (
158+ parser : P ,
159+ declaration : Self ,
160+ ) -> Recursive < Indirect < ' a , ' b , I , O , E > , Defined > {
138161 let location = * Location :: caller ( ) ;
139- self . parser ( )
162+ declaration
163+ . parser ( )
140164 . inner
141165 . set ( Box :: new ( parser) )
142166 . unwrap_or_else ( |_| {
143- panic ! ( "recursive parsers can only be defined once, trying to redefine it at {location}" )
167+ panic ! (
168+ "recursive parsers can only be defined once, trying to redefine it at {location}"
169+ )
144170 } ) ;
171+
172+ Recursive {
173+ state : EmptyPhantom :: new ( ) ,
174+ inner : declaration. inner ,
175+ }
145176 }
146177}
147178
148- impl < P : ?Sized > Recursive < P > {
179+ impl < P : ?Sized , S : RecursiveState > Recursive < P , S > {
149180 #[ inline]
150181 fn parser ( & self ) -> RefC < P > {
151182 match & self . inner {
@@ -157,9 +188,22 @@ impl<P: ?Sized> Recursive<P> {
157188 }
158189}
159190
160- impl < P : ?Sized > Clone for Recursive < P > {
191+ impl < P : ?Sized > Clone for Recursive < P , Declared > {
192+ fn clone ( & self ) -> Self {
193+ Self {
194+ state : EmptyPhantom :: new ( ) ,
195+ inner : match & self . inner {
196+ RecursiveInner :: Owned ( x) => RecursiveInner :: Unowned ( RefC :: downgrade ( x) ) ,
197+ RecursiveInner :: Unowned ( x) => RecursiveInner :: Unowned ( x. clone ( ) ) ,
198+ } ,
199+ }
200+ }
201+ }
202+
203+ impl < P : ?Sized > Clone for Recursive < P , Defined > {
161204 fn clone ( & self ) -> Self {
162205 Self {
206+ state : EmptyPhantom :: new ( ) ,
163207 inner : match & self . inner {
164208 RecursiveInner :: Owned ( x) => RecursiveInner :: Owned ( x. clone ( ) ) ,
165209 RecursiveInner :: Unowned ( x) => RecursiveInner :: Unowned ( x. clone ( ) ) ,
@@ -179,10 +223,11 @@ pub(crate) fn recurse<R, F: FnOnce() -> R>(f: F) -> R {
179223 f ( )
180224}
181225
182- impl < ' a , ' b , I , O , E > ParserSealed < ' a , I , O , E > for Recursive < Indirect < ' a , ' b , I , O , E > >
226+ impl < ' a , ' b , I , O , E , S > ParserSealed < ' a , I , O , E > for Recursive < Indirect < ' a , ' b , I , O , E > , S >
183227where
184228 I : Input < ' a > ,
185229 E : ParserExtra < ' a , I > ,
230+ S : RecursiveState ,
186231{
187232 #[ inline]
188233 fn go < M : Mode > ( & self , inp : & mut InputRef < ' a , ' _ , I , E > ) -> PResult < M , O > {
@@ -201,10 +246,11 @@ where
201246 go_extra ! ( O ) ;
202247}
203248
204- impl < ' a , ' b , I , O , E > ParserSealed < ' a , I , O , E > for Recursive < Direct < ' a , ' b , I , O , E > >
249+ impl < ' a , ' b , I , O , E , S > ParserSealed < ' a , I , O , E > for Recursive < Direct < ' a , ' b , I , O , E > , S >
205250where
206251 I : Input < ' a > ,
207252 E : ParserExtra < ' a , I > ,
253+ S : RecursiveState ,
208254{
209255 #[ inline]
210256 fn go < M : Mode > ( & self , inp : & mut InputRef < ' a , ' _ , I , E > ) -> PResult < M , O > {
@@ -264,23 +310,25 @@ where
264310/// ])));
265311/// ```
266312// INFO: Clone bound not actually needed, but good to be safe for future compat
267- pub fn recursive < ' a , ' b , I , O , E , A , F > ( f : F ) -> Recursive < Direct < ' a , ' b , I , O , E > >
313+ pub fn recursive < ' a , ' b , I , O , E , A , F > ( f : F ) -> Recursive < Direct < ' a , ' b , I , O , E > , Defined >
268314where
269315 I : Input < ' a > ,
270316 E : ParserExtra < ' a , I > ,
271317 A : Parser < ' a , I , O , E > + Clone + MaybeSync + ' b ,
272- F : FnOnce ( Recursive < Direct < ' a , ' b , I , O , E > > ) -> A ,
318+ F : FnOnce ( Recursive < Direct < ' a , ' b , I , O , E > , Declared > ) -> A ,
273319{
274320 let rc = RefC :: new_cyclic ( |rc| {
275321 let rc: RefW < DynParser < ' a , ' b , I , O , E > > = rc. clone ( ) as _ ;
276322 let parser = Recursive {
277323 inner : RecursiveInner :: Unowned ( rc. clone ( ) ) ,
324+ state : EmptyPhantom :: < Declared > :: new ( ) ,
278325 } ;
279326
280327 f ( parser)
281328 } ) ;
282329
283330 Recursive {
284331 inner : RecursiveInner :: Owned ( rc) ,
332+ state : EmptyPhantom :: new ( ) ,
285333 }
286334}
0 commit comments