@@ -216,14 +216,30 @@ pub fn parser<'a>() -> impl Parser<'a, ParserSource<'a>, ParseValues, Extra<'a>>
216216 . to_slice ( )
217217 . map_with ( |ident : & str , e| ident. to_owned ( ) . spanned ( e. span ( ) ) ) ;
218218
219- let path_start = ident. then_ignore ( just ( "::" ) ) . repeated ( ) . collect :: < Vec < _ > > ( ) ;
220- let path_end = ident
221- . map ( PathEnd :: Ident )
222- . or ( just ( "*::" ) . ignore_then ( ident) . map ( PathEnd :: WithIdent ) ) ;
223- let path = path_start
224- . map_with ( |v, e| v. spanned ( e. span ( ) ) )
225- . then ( path_end. map_with ( |v, e| v. spanned ( e. span ( ) ) ) )
226- . map ( |( leading, last) | Path { leading, last } ) ;
219+ let mut path = chumsky:: recursive:: Recursive :: declare ( ) ;
220+ let path_start;
221+ let path_end;
222+ path. define ( {
223+ let ident_with_generics = ident. then ( path. clone ( ) . delimited_by ( just ( '<' ) , just ( '>' ) ) ) ;
224+
225+ path_start = ident. then_ignore ( just ( "::" ) ) . repeated ( ) . collect :: < Vec < _ > > ( ) ;
226+ path_end = ident_with_generics
227+ . clone ( )
228+ . map_with ( |( ident, path) , e| {
229+ PathEnd :: IdentGeneric ( ident, Spanned :: new ( e. span ( ) , Box :: new ( path) ) )
230+ } )
231+ . or ( just ( "*::" )
232+ . ignore_then ( ident_with_generics)
233+ . map_with ( |( ident, path) , e| {
234+ PathEnd :: WithIdentGeneric ( ident, Spanned :: new ( e. span ( ) , Box :: new ( path) ) )
235+ } ) )
236+ . or ( ident. map ( PathEnd :: Ident ) )
237+ . or ( just ( "*::" ) . ignore_then ( ident) . map ( PathEnd :: WithIdent ) ) ;
238+ path_start
239+ . map_with ( |v, e| v. spanned ( e. span ( ) ) )
240+ . then ( path_end. clone ( ) . map_with ( |v, e| v. spanned ( e. span ( ) ) ) )
241+ . map ( |( leading, last) | Path { leading, last } )
242+ } ) ;
227243
228244 let uses = just ( "use" )
229245 . padded_by ( comments)
@@ -457,20 +473,22 @@ pub fn parser<'a>() -> impl Parser<'a, ParserSource<'a>, ParseValues, Extra<'a>>
457473 |_| IndexMap :: < Ident , ParseVal > :: new ( ) ,
458474 ) ) ) ;
459475
460- let reference = just ( '$' ) . ignore_then ( path) . map ( |path| {
476+ let reference = just ( '$' ) . ignore_then ( path. clone ( ) ) . map ( |path| {
461477 // We have at least 1 element in the path.
462478 Value :: Ref ( path)
463479 } ) ;
464480
465- let path_p = path. padded_by ( comments) . padded ( ) ;
481+ let path_p = path. clone ( ) . padded_by ( comments) . padded ( ) ;
466482
467483 // Parser for tuple structs
468484 let unnamed_struct = path_p
485+ . clone ( )
469486 . then ( tuple. clone ( ) )
470487 . map ( |( name, fields) | ( Some ( name) , Value :: Struct ( FieldsKind :: Unnamed ( fields) ) ) ) ;
471488
472489 // Parser for structs
473490 let named_struct = path_p
491+ . clone ( )
474492 . then ( structure. clone ( ) )
475493 . map ( |( name, fields) | ( Some ( name) , Value :: Struct ( FieldsKind :: Named ( fields) ) ) ) ;
476494
@@ -503,16 +521,19 @@ pub fn parser<'a>() -> impl Parser<'a, ParserSource<'a>, ParseValues, Extra<'a>>
503521 // - `| Path::B`
504522 // - `|`
505523 let path_or = path_p
524+ . clone ( )
506525 . separated_by ( just ( '|' ) . padded_by ( comments) )
507526 . allow_leading ( )
508527 . at_least ( 2 )
509528 . collect ( )
510529 . or ( just ( '|' )
511- . ignore_then ( path_p. or_not ( ) )
530+ . ignore_then ( path_p. clone ( ) . or_not ( ) )
512531 . map ( |p| p. into_iter ( ) . collect ( ) ) )
513532 . map ( Value :: Or ) ;
514533
515- let path_value = path. map ( |path : Path | ( Some ( path) , Value :: Struct ( FieldsKind :: Unit ) ) ) ;
534+ let path_value = path
535+ . clone ( )
536+ . map ( |path : Path | ( Some ( path) , Value :: Struct ( FieldsKind :: Unit ) ) ) ;
516537
517538 // The start of a raw string: count the number of open braces
518539 let start_raw = just ( '{' ) . repeated ( ) . at_least ( 1 ) . count ( ) ;
@@ -562,6 +583,7 @@ pub fn parser<'a>() -> impl Parser<'a, ParserSource<'a>, ParseValues, Extra<'a>>
562583 . boxed ( ) ;
563584
564585 let ty_specification = path
586+ . clone ( )
565587 . delimited_by (
566588 just ( '<' ) . padded_by ( comments) . padded ( ) ,
567589 just ( '>' ) . padded_by ( comments) . padded ( ) ,
@@ -625,9 +647,10 @@ pub fn parser<'a>() -> impl Parser<'a, ParserSource<'a>, ParseValues, Extra<'a>>
625647 uses. then (
626648 just ( "copy" )
627649 . padded ( )
628- . ignore_then ( binding ( ident, object. clone ( ) , path, comments) )
650+ . ignore_then ( binding ( ident, object. clone ( ) , path. clone ( ) , comments) )
629651 . map ( |binding| ( binding, ItemType :: Copy ) )
630- . or ( binding ( ident, object, path, comments) . map ( |binding| ( binding, ItemType :: Value ) ) )
652+ . or ( binding ( ident, object, path. clone ( ) , comments)
653+ . map ( |binding| ( binding, ItemType :: Value ) ) )
631654 . repeated ( )
632655 . collect :: < Vec < _ > > ( ) ,
633656 )
0 commit comments