Repository: kevinmehall/rust-peg (language: rust)

Issue:
feat: in rule where clauses support
```rust
use std::str::FromStr;

peg::parser! {
    grammar parser() for str {
        pub rule foo<T: FromStr>() -> T
        //where <T as FromStr>::Err: Debug // peg not support where
            = s:$(['0'..='9']+)
        {
            s.parse().unwrap()
        }
    }
}
```


Discussion / hints:

Fix patch:
diff --git a/peg-macros/ast.rs b/peg-macros/ast.rs
index 6002fe5..1ed3712 100644
--- a/peg-macros/ast.rs
+++ b/peg-macros/ast.rs
@@ -40,6 +40,7 @@ pub struct Rule {
     pub params: Vec<RuleParam>,
     pub expr: SpannedExpr,
     pub ret_type: Option<TokenStream>,
+    pub where_clause: Option<TokenStream>,
     pub doc: Option<TokenStream>,
     pub visibility: Option<TokenStream>,
     pub cache: Option<Cache>,
diff --git a/peg-macros/grammar.rs b/peg-macros/grammar.rs
index ca094f7..f7debea 100644
--- a/peg-macros/grammar.rs
+++ b/peg-macros/grammar.rs
@@ -206,14 +206,36 @@ pub mod peg {
                 };
                 match __seq_res {
                     ::peg::RuleResult::Matched(__pos, p) => {
-                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ">") {
+                        let __seq_res = match match ::peg::ParseLiteral::parse_string_literal(
+                            __input, __pos, ",",
+                        ) {
                             ::peg::RuleResult::Matched(__pos, __val) => {
-                                ::peg::RuleResult::Matched(__pos, (|| p)())
+                                ::peg::RuleResult::Matched(__pos, __val)
                             }
                             ::peg::RuleResult::Failed => {
-                                __err_state.mark_failure(__pos, "\">\"");
+                                __err_state.mark_failure(__pos, "\",\"");
                                 ::peg::RuleResult::Failed
                             }
+                        } {
+                            ::peg::RuleResult::Matched(__newpos, _) => {
+                                ::peg::RuleResult::Matched(__newpos, ())
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, ()),
+                        };
+                        match __seq_res {
+                            ::peg::RuleResult::Matched(__pos, _) => {
+                                match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ">")
+                                {
+                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                        ::peg::RuleResult::Matched(__pos, (|| p)())
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        __err_state.mark_failure(__pos, "\">\"");
+                                        ::peg::RuleResult::Failed
+                                    }
+                                }
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
                         }
                     }
                     ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
@@ -446,7 +468,7 @@ pub mod peg {
                                                                     header,
                                                                 ) => {
                                                                     let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "->") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = { let str_start = __pos ; match match __parse_rust_type (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , :: peg :: ParseSlice :: parse_slice (__input , str_start , __newpos)) } , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , t) => { :: peg :: RuleResult :: Matched (__pos , (|| { t }) ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"->\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , __value) => { :: peg :: RuleResult :: Matched (__newpos , Some (__value)) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , None) } , } ;
-                                                                    match __seq_res { :: peg :: RuleResult :: Matched (__pos , ret_type) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "=") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = __parse_expression (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , expr) => { { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ";") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\";\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , (|| { Rule { span , doc , name : header . 0 , ty_params : header . 1 , params : header . 2 , expr , ret_type , visibility , no_eof , cache } }) ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"=\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                                    match __seq_res { :: peg :: RuleResult :: Matched (__pos , ret_type) => { { let __seq_res = match { let str_start = __pos ; match match __parse_rust_where_clause (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , :: peg :: ParseSlice :: parse_slice (__input , str_start , __newpos)) } , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } { :: peg :: RuleResult :: Matched (__newpos , __value) => { :: peg :: RuleResult :: Matched (__newpos , Some (__value)) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , None) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , where_clause) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "=") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = __parse_expression (__input , __state , __err_state , __pos) ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , expr) => { { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ";") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\";\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , (|| { Rule { span , doc , name : header . 0 , ty_params : header . 1 , params : header . 2 , expr , ret_type , where_clause , visibility , no_eof , cache } }) ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"=\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
                                                                 }
                                                                 ::peg::RuleResult::Failed => {
                                                                     ::peg::RuleResult::Failed
@@ -747,15 +769,85 @@ pub mod peg {
         #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
         match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "(") {
             ::peg::RuleResult::Matched(__pos, __val) => {
-                let __seq_res = {
-                    let mut __repeat_pos = __pos;
-                    let mut __repeat_value = vec![];
-                    loop {
-                        let __pos = __repeat_pos;
-                        let __pos = if __repeat_value.is_empty() {
-                            __pos
+                let __seq_res = match {
+                    let __seq_res = {
+                        let mut __repeat_pos = __pos;
+                        let mut __repeat_value = vec![];
+                        loop {
+                            let __pos = __repeat_pos;
+                            let __pos = if __repeat_value.is_empty() {
+                                __pos
+                            } else {
+                                let __sep_res = match ::peg::ParseLiteral::parse_string_literal(
+                                    __input, __pos, ",",
+                                ) {
+                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                        ::peg::RuleResult::Matched(__pos, __val)
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        __err_state.mark_failure(__pos, "\",\"");
+                                        ::peg::RuleResult::Failed
+                                    }
+                                };
+                                match __sep_res {
+                                    ::peg::RuleResult::Matched(__newpos, _) => __newpos,
+                                    ::peg::RuleResult::Failed => break,
+                                }
+                            };
+                            let __step_res = {
+                                let __seq_res = __parse_IDENT(__input, __state, __err_state, __pos);
+                                match __seq_res {
+                                    ::peg::RuleResult::Matched(__pos, name) => {
+                                        match ::peg::ParseLiteral::parse_string_literal(
+                                            __input, __pos, ":",
+                                        ) {
+                                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                                let __seq_res = __parse_rule_param_ty(
+                                                    __input,
+                                                    __state,
+                                                    __err_state,
+                                                    __pos,
+                                                );
+                                                match __seq_res {
+                                                    ::peg::RuleResult::Matched(__pos, ty) => {
+                                                        ::peg::RuleResult::Matched(
+                                                            __pos,
+                                                            (|| RuleParam { name, ty })(),
+                                                        )
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                }
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                __err_state.mark_failure(__pos, "\":\"");
+                                                ::peg::RuleResult::Failed
+                                            }
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                }
+                            };
+                            match __step_res {
+                                ::peg::RuleResult::Matched(__newpos, __value) => {
+                                    __repeat_pos = __newpos;
+                                    __repeat_value.push(__value);
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    break;
+                                }
+                            }
+                        }
+                        if __repeat_value.len() >= 1 {
+                            ::peg::RuleResult::Matched(__repeat_pos, __repeat_value)
                         } else {
-                            let __sep_res = match ::peg::ParseLiteral::parse_string_literal(
+                            ::peg::RuleResult::Failed
+                        }
+                    };
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, x) => {
+                            let __seq_res = match match ::peg::ParseLiteral::parse_string_literal(
                                 __input, __pos, ",",
                             ) {
                                 ::peg::RuleResult::Matched(__pos, __val) => {
@@ -765,64 +857,32 @@ pub mod peg {
                                     __err_state.mark_failure(__pos, "\",\"");
                                     ::peg::RuleResult::Failed
                                 }
+                            } {
+                                ::peg::RuleResult::Matched(__newpos, _) => {
+                                    ::peg::RuleResult::Matched(__newpos, ())
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, ()),
                             };
-                            match __sep_res {
-                                ::peg::RuleResult::Matched(__newpos, _) => __newpos,
-                                ::peg::RuleResult::Failed => break,
-                            }
-                        };
-                        let __step_res = {
-                            let __seq_res = __parse_IDENT(__input, __state, __err_state, __pos);
                             match __seq_res {
-                                ::peg::RuleResult::Matched(__pos, name) => {
-                                    match ::peg::ParseLiteral::parse_string_literal(
-                                        __input, __pos, ":",
-                                    ) {
-                                        ::peg::RuleResult::Matched(__pos, __val) => {
-                                            let __seq_res = __parse_rule_param_ty(
-                                                __input,
-                                                __state,
-                                                __err_state,
-                                                __pos,
-                                            );
-                                            match __seq_res {
-                                                ::peg::RuleResult::Matched(__pos, ty) => {
-                                                    ::peg::RuleResult::Matched(
-                                                        __pos,
-                                                        (|| RuleParam { name, ty })(),
-                                                    )
-                                                }
-                                                ::peg::RuleResult::Failed => {
-                                                    ::peg::RuleResult::Failed
-                                                }
-                                            }
-                                        }
-                                        ::peg::RuleResult::Failed => {
-                                            __err_state.mark_failure(__pos, "\":\"");
-                                            ::peg::RuleResult::Failed
-                                        }
-                                    }
+                                ::peg::RuleResult::Matched(__pos, _) => {
+                                    ::peg::RuleResult::Matched(__pos, (|| x)())
                                 }
                                 ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
                             }
-                        };
-                        match __step_res {
-                            ::peg::RuleResult::Matched(__newpos, __value) => {
-                                __repeat_pos = __newpos;
-                                __repeat_value.push(__value);
-                            }
-                            ::peg::RuleResult::Failed => {
-                                break;
-                            }
                         }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
                     }
-                    ::peg::RuleResult::Matched(__repeat_pos, __repeat_value)
+                } {
+                    ::peg::RuleResult::Matched(__newpos, __value) => {
+                        ::peg::RuleResult::Matched(__newpos, Some(__value))
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, None),
                 };
                 match __seq_res {
                     ::peg::RuleResult::Matched(__pos, params) => {
                         match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ")") {
                             ::peg::RuleResult::Matched(__pos, __val) => {
-                                ::peg::RuleResult::Matched(__pos, (|| params)())
+                                ::peg::RuleResult::Matched(__pos, (|| params.unwrap_or_default())())
                             }
                             ::peg::RuleResult::Failed => {
                                 __err_state.mark_failure(__pos, "\")\"");
@@ -1058,7 +1118,7 @@ pub mod peg {
                                             ::peg::RuleResult::Matched(__pos, __value)
                                         }
                                         ::peg::RuleResult::Failed => {
-                                            let __choice_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "::") { :: peg :: RuleResult :: Matched (__pos , __val) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "{") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = { let mut __repeat_pos = __pos ; let mut __repeat_value = vec ! () ; loop { let __pos = __repeat_pos ; let __pos = if __repeat_value . is_empty () { __pos } else { let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } ; match __sep_res { :: peg :: RuleResult :: Matched (__newpos , _) => { __newpos } , :: peg :: RuleResult :: Failed => break , } } ; let __step_res = { let __seq_res = match __parse_IDENT (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "as") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = match __parse_IDENT (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"as\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } ; match __step_res { :: peg :: RuleResult :: Matched (__newpos , __value) => { __repeat_pos = __newpos ; __repeat_value . push (__value) ; } , :: peg :: RuleResult :: Failed => { break ; } } } if __repeat_value . len () >= 1 { :: peg :: RuleResult :: Matched (__repeat_pos , ()) } else { :: peg :: RuleResult :: Failed } } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "}") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"}\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"{\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"::\"") ; :: peg :: RuleResult :: Failed } } ;
+                                            let __choice_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "::") { :: peg :: RuleResult :: Matched (__pos , __val) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "{") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = { let __seq_res = { let mut __repeat_pos = __pos ; let mut __repeat_value = vec ! () ; loop { let __pos = __repeat_pos ; let __pos = if __repeat_value . is_empty () { __pos } else { let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } ; match __sep_res { :: peg :: RuleResult :: Matched (__newpos , _) => { __newpos } , :: peg :: RuleResult :: Failed => break , } } ; let __step_res = { let __seq_res = match __parse_IDENT (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "as") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = match __parse_IDENT (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"as\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } ; match __step_res { :: peg :: RuleResult :: Matched (__newpos , __value) => { __repeat_pos = __newpos ; __repeat_value . push (__value) ; } , :: peg :: RuleResult :: Failed => { break ; } } } if __repeat_value . len () >= 1 { :: peg :: RuleResult :: Matched (__repeat_pos , ()) } else { :: peg :: RuleResult :: Failed } } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "}") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"}\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"{\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"::\"") ; :: peg :: RuleResult :: Failed } } ;
                                             match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "as") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = match __parse_IDENT (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"as\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } }
                                         }
                                     }
@@ -1297,16 +1357,65 @@ pub mod peg {
                                 __input, __pos, "dyn",
                             ) {
                                 ::peg::RuleResult::Matched(__pos, __val) => {
-                                    let __seq_res = match __parse_rust_type(
-                                        __input,
-                                        __state,
-                                        __err_state,
-                                        __pos,
-                                    ) {
-                                        ::peg::RuleResult::Matched(pos, _) => {
-                                            ::peg::RuleResult::Matched(pos, ())
+                                    let __seq_res = {
+                                        let mut __repeat_pos = __pos;
+                                        let mut __repeat_value = vec![];
+                                        loop {
+                                            let __pos = __repeat_pos;
+                                            let __pos = if __repeat_value.is_empty() {
+                                                __pos
+                                            } else {
+                                                let __sep_res =
+                                                    match ::peg::ParseLiteral::parse_string_literal(
+                                                        __input, __pos, "+",
+                                                    ) {
+                                                        ::peg::RuleResult::Matched(
+                                                            __pos,
+                                                            __val,
+                                                        ) => {
+                                                            ::peg::RuleResult::Matched(__pos, __val)
+                                                        }
+                                                        ::peg::RuleResult::Failed => {
+                                                            __err_state
+                                                                .mark_failure(__pos, "\"+\"");
+                                                            ::peg::RuleResult::Failed
+                                                        }
+                                                    };
+                                                match __sep_res {
+                                                    ::peg::RuleResult::Matched(__newpos, _) => {
+                                                        __newpos
+                                                    }
+                                                    ::peg::RuleResult::Failed => break,
+                                                }
+                                            };
+                                            let __step_res = match __parse_rust_type(
+                                                __input,
+                                                __state,
+                                                __err_state,
+                                                __pos,
+                                            ) {
+                                                ::peg::RuleResult::Matched(pos, _) => {
+                                                    ::peg::RuleResult::Matched(pos, ())
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            };
+                                            match __step_res {
+                                                ::peg::RuleResult::Matched(__newpos, __value) => {
+                                                    __repeat_pos = __newpos;
+                                                    __repeat_value.push(__value);
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    break;
+                                                }
+                                            }
+                                        }
+                                        if __repeat_value.len() >= 1 {
+                                            ::peg::RuleResult::Matched(__repeat_pos, ())
+                                        } else {
+                                            ::peg::RuleResult::Failed
                                         }
-                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
                                     };
                                     match __seq_res {
                                         ::peg::RuleResult::Matched(__pos, _) => {
@@ -1330,16 +1439,52 @@ pub mod peg {
                                             __input, __pos, "impl",
                                         ) {
                                             ::peg::RuleResult::Matched(__pos, __val) => {
-                                                let __seq_res = match __parse_rust_type(
-                                                    __input,
-                                                    __state,
-                                                    __err_state,
-                                                    __pos,
-                                                ) {
-                                                    ::peg::RuleResult::Matched(pos, _) => {
-                                                        ::peg::RuleResult::Matched(pos, ())
+                                                let __seq_res = {
+                                                    let mut __repeat_pos = __pos;
+                                                    let mut __repeat_value = vec![];
+                                                    loop {
+                                                        let __pos = __repeat_pos;
+                                                        let __pos = if __repeat_value.is_empty() {
+                                                            __pos
+                                                        } else {
+                                                            let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "+") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"+\"") ; :: peg :: RuleResult :: Failed } } ;
+                                                            match __sep_res {
+                                                                ::peg::RuleResult::Matched(
+                                                                    __newpos,
+                                                                    _,
+                                                                ) => __newpos,
+                                                                ::peg::RuleResult::Failed => break,
+                                                            }
+                                                        };
+                                                        let __step_res = match __parse_rust_type(
+                                                            __input,
+                                                            __state,
+                                                            __err_state,
+                                                            __pos,
+                                                        ) {
+                                                            ::peg::RuleResult::Matched(pos, _) => {
+                                                                ::peg::RuleResult::Matched(pos, ())
+                                                            }
+                                                            ::peg::RuleResult::Failed => {
+                                                                ::peg::RuleResult::Failed
+                                                            }
+                                                        };
+                                                        match __step_res {
+                                                            ::peg::RuleResult::Matched(
+                                                                __newpos,
+                                                                __value,
+                                                            ) => {
+                                                                __repeat_pos = __newpos;
+                                                                __repeat_value.push(__value);
+                                                            }
+                                                            ::peg::RuleResult::Failed => {
+                                                                break;
+                                                            }
+                                                        }
                                                     }
-                                                    ::peg::RuleResult::Failed => {
+                                                    if __repeat_value.len() >= 1 {
+                                                        ::peg::RuleResult::Matched(__repeat_pos, ())
+                                                    } else {
                                                         ::peg::RuleResult::Failed
                                                     }
                                                 };
@@ -1367,38 +1512,58 @@ pub mod peg {
                                                     __input, __pos, "(",
                                                 ) {
                                                     ::peg::RuleResult::Matched(__pos, __val) => {
-                                                        let __seq_res = {
-                                                            let mut __repeat_pos = __pos;
-                                                            let mut __repeat_value = vec![];
-                                                            loop {
-                                                                let __pos = __repeat_pos;
-                                                                let __pos = if __repeat_value
-                                                                    .is_empty()
-                                                                {
-                                                                    __pos
-                                                                } else {
-                                                                    let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } ;
-                                                                    match __sep_res { :: peg :: RuleResult :: Matched (__newpos , _) => { __newpos } , :: peg :: RuleResult :: Failed => break , }
-                                                                };
-                                                                let __step_res = match __parse_rust_type (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ;
-                                                                match __step_res {
+                                                        let __seq_res = match {
+                                                            let __seq_res = {
+                                                                let mut __repeat_pos = __pos;
+                                                                let mut __repeat_value = vec![];
+                                                                loop {
+                                                                    let __pos = __repeat_pos;
+                                                                    let __pos = if __repeat_value
+                                                                        .is_empty()
+                                                                    {
+                                                                        __pos
+                                                                    } else {
+                                                                        let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } ;
+                                                                        match __sep_res { :: peg :: RuleResult :: Matched (__newpos , _) => { __newpos } , :: peg :: RuleResult :: Failed => break , }
+                                                                    };
+                                                                    let __step_res = match __parse_rust_type (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ;
+                                                                    match __step_res { :: peg :: RuleResult :: Matched (__newpos , __value) => { __repeat_pos = __newpos ; __repeat_value . push (__value) ; } , :: peg :: RuleResult :: Failed => { break ; } }
+                                                                }
+                                                                if __repeat_value.len() >= 1 {
                                                                     ::peg::RuleResult::Matched(
-                                                                        __newpos,
-                                                                        __value,
-                                                                    ) => {
-                                                                        __repeat_pos = __newpos;
-                                                                        __repeat_value
-                                                                            .push(__value);
-                                                                    }
-                                                                    ::peg::RuleResult::Failed => {
-                                                                        break;
-                                                                    }
+                                                                        __repeat_pos,
+                                                                        (),
+                                                                    )
+                                                                } else {
+                                                                    ::peg::RuleResult::Failed
+                                                                }
+                                                            };
+                                                            match __seq_res {
+                                                                ::peg::RuleResult::Matched(
+                                                                    __pos,
+                                                                    _,
+                                                                ) => {
+                                                                    let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ;
+                                                                    match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                                }
+                                                                ::peg::RuleResult::Failed => {
+                                                                    ::peg::RuleResult::Failed
                                                                 }
                                                             }
+                                                        } {
                                                             ::peg::RuleResult::Matched(
-                                                                __repeat_pos,
+                                                                __newpos,
+                                                                _,
+                                                            ) => ::peg::RuleResult::Matched(
+                                                                __newpos,
                                                                 (),
-                                                            )
+                                                            ),
+                                                            ::peg::RuleResult::Failed => {
+                                                                ::peg::RuleResult::Matched(
+                                                                    __pos,
+                                                                    (),
+                                                                )
+                                                            }
                                                         };
                                                         match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ")") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\")\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
                                                     }
@@ -1412,14 +1577,41 @@ pub mod peg {
                                                     ::peg::RuleResult::Matched(__pos, __value)
                                                 }
                                                 ::peg::RuleResult::Failed => {
-                                                    match __parse_rust_ty_path(
-                                                        __input,
-                                                        __state,
-                                                        __err_state,
-                                                        __pos,
-                                                    ) {
-                                                        ::peg::RuleResult::Matched(pos, _) => {
-                                                            ::peg::RuleResult::Matched(pos, ())
+                                                    let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "<") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = match __parse_rust_type (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "as") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = match __parse_rust_ty_path (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"as\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ">") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\">\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"<\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ;
+                                                    match __seq_res {
+                                                        ::peg::RuleResult::Matched(__pos, _) => {
+                                                            let __seq_res =
+                                                                match __parse_rust_ty_path(
+                                                                    __input,
+                                                                    __state,
+                                                                    __err_state,
+                                                                    __pos,
+                                                                ) {
+                                                                    ::peg::RuleResult::Matched(
+                                                                        pos,
+                                                                        _,
+                                                                    ) => {
+                                                                        ::peg::RuleResult::Matched(
+                                                                            pos,
+                                                                            (),
+                                                                        )
+                                                                    }
+                                                                    ::peg::RuleResult::Failed => {
+                                                                        ::peg::RuleResult::Failed
+                                                                    }
+                                                                };
+                                                            match __seq_res {
+                                                                ::peg::RuleResult::Matched(
+                                                                    __pos,
+                                                                    _,
+                                                                ) => ::peg::RuleResult::Matched(
+                                                                    __pos,
+                                                                    (),
+                                                                ),
+                                                                ::peg::RuleResult::Failed => {
+                                                                    ::peg::RuleResult::Failed
+                                                                }
+                                                            }
                                                         }
                                                         ::peg::RuleResult::Failed => {
                                                             ::peg::RuleResult::Failed
@@ -1480,28 +1672,428 @@ pub mod peg {
                                         __err_state.mark_failure(__pos, "\"::\"");
                                         ::peg::RuleResult::Failed
                                     }
-                                };
-                                match __sep_res {
-                                    ::peg::RuleResult::Matched(__newpos, _) => __newpos,
-                                    ::peg::RuleResult::Failed => break,
+                                };
+                                match __sep_res {
+                                    ::peg::RuleResult::Matched(__newpos, _) => __newpos,
+                                    ::peg::RuleResult::Failed => break,
+                                }
+                            };
+                            let __step_res = {
+                                let __seq_res =
+                                    match __parse_IDENT(__input, __state, __err_state, __pos) {
+                                        ::peg::RuleResult::Matched(pos, _) => {
+                                            ::peg::RuleResult::Matched(pos, ())
+                                        }
+                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                    };
+                                match __seq_res {
+                                    ::peg::RuleResult::Matched(__pos, _) => {
+                                        let __seq_res = match {
+                                            let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "::") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"::\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ;
+                                            match __seq_res {
+                                                ::peg::RuleResult::Matched(__pos, _) => {
+                                                    let __seq_res = {
+                                                        let __choice_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "<") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = { let mut __repeat_pos = __pos ; let mut __repeat_value = vec ! () ; loop { let __pos = __repeat_pos ; let __pos = if __repeat_value . is_empty () { __pos } else { let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } ; match __sep_res { :: peg :: RuleResult :: Matched (__newpos , _) => { __newpos } , :: peg :: RuleResult :: Failed => break , } } ; let __step_res = { let __choice_res = match __parse_LIFETIME (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => { let __choice_res = match __parse_rust_type (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => { let __choice_res = match __parse_BRACE_GROUP (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => match __parse_LITERAL (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } } } } } ; match __step_res { :: peg :: RuleResult :: Matched (__newpos , __value) => { __repeat_pos = __newpos ; __repeat_value . push (__value) ; } , :: peg :: RuleResult :: Failed => { break ; } } } if __repeat_value . len () >= 1 { :: peg :: RuleResult :: Matched (__repeat_pos , ()) } else { :: peg :: RuleResult :: Failed } } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ">") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\">\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"<\"") ; :: peg :: RuleResult :: Failed } } ;
+                                                        match __choice_res {
+                                                            ::peg::RuleResult::Matched(
+                                                                __pos,
+                                                                __value,
+                                                            ) => ::peg::RuleResult::Matched(
+                                                                __pos, __value,
+                                                            ),
+                                                            ::peg::RuleResult::Failed => {
+                                                                let __seq_res = match __parse_PAREN_GROUP (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ;
+                                                                match __seq_res {
+                                                                    ::peg::RuleResult::Matched(
+                                                                        __pos,
+                                                                        _,
+                                                                    ) => {
+                                                                        let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "->") { :: peg :: RuleResult :: Matched (__pos , __val) => { { let __seq_res = match __parse_rust_type (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"->\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ;
+                                                                        match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                                    }
+                                                                    ::peg::RuleResult::Failed => {
+                                                                        ::peg::RuleResult::Failed
+                                                                    }
+                                                                }
+                                                            }
+                                                        }
+                                                    };
+                                                    match __seq_res {
+                                                        ::peg::RuleResult::Matched(__pos, _) => {
+                                                            ::peg::RuleResult::Matched(__pos, ())
+                                                        }
+                                                        ::peg::RuleResult::Failed => {
+                                                            ::peg::RuleResult::Failed
+                                                        }
+                                                    }
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            }
+                                        } {
+                                            ::peg::RuleResult::Matched(__newpos, _) => {
+                                                ::peg::RuleResult::Matched(__newpos, ())
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                ::peg::RuleResult::Matched(__pos, ())
+                                            }
+                                        };
+                                        match __seq_res {
+                                            ::peg::RuleResult::Matched(__pos, _) => {
+                                                ::peg::RuleResult::Matched(__pos, ())
+                                            }
+                                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                }
+                            };
+                            match __step_res {
+                                ::peg::RuleResult::Matched(__newpos, __value) => {
+                                    __repeat_pos = __newpos;
+                                    __repeat_value.push(__value);
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    break;
+                                }
+                            }
+                        }
+                        if __repeat_value.len() >= 1 {
+                            ::peg::RuleResult::Matched(__repeat_pos, ())
+                        } else {
+                            ::peg::RuleResult::Failed
+                        }
+                    };
+                    match __seq_res {
+                        ::peg::RuleResult::Matched(__pos, _) => {
+                            ::peg::RuleResult::Matched(__pos, ())
+                        }
+                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                    }
+                }
+                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+            }
+        }
+    }
+    fn __parse_rust_ty_params<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<Vec<TokenStream>> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "<") {
+            ::peg::RuleResult::Matched(__pos, __val) => {
+                let __seq_res = {
+                    let mut __repeat_pos = __pos;
+                    let mut __repeat_value = vec![];
+                    loop {
+                        let __pos = __repeat_pos;
+                        let __pos = if __repeat_value.is_empty() {
+                            __pos
+                        } else {
+                            let __sep_res = match ::peg::ParseLiteral::parse_string_literal(
+                                __input, __pos, ",",
+                            ) {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    ::peg::RuleResult::Matched(__pos, __val)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\",\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            };
+                            match __sep_res {
+                                ::peg::RuleResult::Matched(__newpos, _) => __newpos,
+                                ::peg::RuleResult::Failed => break,
+                            }
+                        };
+                        let __step_res = {
+                            let str_start = __pos;
+                            match match __parse_rust_generic_param(
+                                __input,
+                                __state,
+                                __err_state,
+                                __pos,
+                            ) {
+                                ::peg::RuleResult::Matched(pos, _) => {
+                                    ::peg::RuleResult::Matched(pos, ())
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            } {
+                                ::peg::RuleResult::Matched(__newpos, _) => {
+                                    ::peg::RuleResult::Matched(
+                                        __newpos,
+                                        ::peg::ParseSlice::parse_slice(
+                                            __input, str_start, __newpos,
+                                        ),
+                                    )
+                                }
+                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                            }
+                        };
+                        match __step_res {
+                            ::peg::RuleResult::Matched(__newpos, __value) => {
+                                __repeat_pos = __newpos;
+                                __repeat_value.push(__value);
+                            }
+                            ::peg::RuleResult::Failed => {
+                                break;
+                            }
+                        }
+                    }
+                    if __repeat_value.len() >= 1 {
+                        ::peg::RuleResult::Matched(__repeat_pos, __repeat_value)
+                    } else {
+                        ::peg::RuleResult::Failed
+                    }
+                };
+                match __seq_res {
+                    ::peg::RuleResult::Matched(__pos, p) => {
+                        let __seq_res = match match ::peg::ParseLiteral::parse_string_literal(
+                            __input, __pos, ",",
+                        ) {
+                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                ::peg::RuleResult::Matched(__pos, __val)
+                            }
+                            ::peg::RuleResult::Failed => {
+                                __err_state.mark_failure(__pos, "\",\"");
+                                ::peg::RuleResult::Failed
+                            }
+                        } {
+                            ::peg::RuleResult::Matched(__newpos, _) => {
+                                ::peg::RuleResult::Matched(__newpos, ())
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, ()),
+                        };
+                        match __seq_res {
+                            ::peg::RuleResult::Matched(__pos, _) => {
+                                match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ">")
+                                {
+                                    ::peg::RuleResult::Matched(__pos, __val) => {
+                                        ::peg::RuleResult::Matched(__pos, (|| p)())
+                                    }
+                                    ::peg::RuleResult::Failed => {
+                                        __err_state.mark_failure(__pos, "\">\"");
+                                        ::peg::RuleResult::Failed
+                                    }
+                                }
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                        }
+                    }
+                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                }
+            }
+            ::peg::RuleResult::Failed => {
+                __err_state.mark_failure(__pos, "\"<\"");
+                ::peg::RuleResult::Failed
+            }
+        }
+    }
+    fn __parse_rust_where_clause<'input>(
+        __input: &'input Input,
+        __state: &mut ParseState<'input>,
+        __err_state: &mut ::peg::error::ErrorState,
+        __pos: usize,
+    ) -> ::peg::RuleResult<()> {
+        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
+        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "where") {
+            ::peg::RuleResult::Matched(__pos, __val) => {
+                let __seq_res = {
+                    let mut __repeat_pos = __pos;
+                    let mut __repeat_value = vec![];
+                    loop {
+                        let __pos = __repeat_pos;
+                        let __pos = if __repeat_value.is_empty() {
+                            __pos
+                        } else {
+                            let __sep_res = match ::peg::ParseLiteral::parse_string_literal(
+                                __input, __pos, ",",
+                            ) {
+                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                    ::peg::RuleResult::Matched(__pos, __val)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    __err_state.mark_failure(__pos, "\",\"");
+                                    ::peg::RuleResult::Failed
+                                }
+                            };
+                            match __sep_res {
+                                ::peg::RuleResult::Matched(__newpos, _) => __newpos,
+                                ::peg::RuleResult::Failed => break,
+                            }
+                        };
+                        let __step_res = {
+                            let __choice_res = {
+                                let __seq_res =
+                                    match __parse_LIFETIME(__input, __state, __err_state, __pos) {
+                                        ::peg::RuleResult::Matched(pos, _) => {
+                                            ::peg::RuleResult::Matched(pos, ())
+                                        }
+                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                    };
+                                match __seq_res {
+                                    ::peg::RuleResult::Matched(__pos, _) => {
+                                        let __seq_res =
+                                            match match ::peg::ParseLiteral::parse_string_literal(
+                                                __input, __pos, ":",
+                                            ) {
+                                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                                    let __seq_res = {
+                                                        let mut __repeat_pos = __pos;
+                                                        let mut __repeat_value = vec![];
+                                                        loop {
+                                                            let __pos = __repeat_pos;
+                                                            let __pos = if __repeat_value.is_empty()
+                                                            {
+                                                                __pos
+                                                            } else {
+                                                                let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "+") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"+\"") ; :: peg :: RuleResult :: Failed } } ;
+                                                                match __sep_res {
+                                                                    ::peg::RuleResult::Matched(
+                                                                        __newpos,
+                                                                        _,
+                                                                    ) => __newpos,
+                                                                    ::peg::RuleResult::Failed => {
+                                                                        break
+                                                                    }
+                                                                }
+                                                            };
+                                                            let __step_res = match __parse_LIFETIME(
+                                                                __input,
+                                                                __state,
+                                                                __err_state,
+                                                                __pos,
+                                                            ) {
+                                                                ::peg::RuleResult::Matched(
+                                                                    pos,
+                                                                    _,
+                                                                ) => ::peg::RuleResult::Matched(
+                                                                    pos,
+                                                                    (),
+                                                                ),
+                                                                ::peg::RuleResult::Failed => {
+                                                                    ::peg::RuleResult::Failed
+                                                                }
+                                                            };
+                                                            match __step_res {
+                                                                ::peg::RuleResult::Matched(
+                                                                    __newpos,
+                                                                    __value,
+                                                                ) => {
+                                                                    __repeat_pos = __newpos;
+                                                                    __repeat_value.push(__value);
+                                                                }
+                                                                ::peg::RuleResult::Failed => {
+                                                                    break;
+                                                                }
+                                                            }
+                                                        }
+                                                        if __repeat_value.len() >= 1 {
+                                                            ::peg::RuleResult::Matched(
+                                                                __repeat_pos,
+                                                                (),
+                                                            )
+                                                        } else {
+                                                            ::peg::RuleResult::Failed
+                                                        }
+                                                    };
+                                                    match __seq_res {
+                                                        ::peg::RuleResult::Matched(__pos, _) => {
+                                                            ::peg::RuleResult::Matched(__pos, ())
+                                                        }
+                                                        ::peg::RuleResult::Failed => {
+                                                            ::peg::RuleResult::Failed
+                                                        }
+                                                    }
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    __err_state.mark_failure(__pos, "\":\"");
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            } {
+                                                ::peg::RuleResult::Matched(__newpos, _) => {
+                                                    ::peg::RuleResult::Matched(__newpos, ())
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Matched(__pos, ())
+                                                }
+                                            };
+                                        match __seq_res {
+                                            ::peg::RuleResult::Matched(__pos, _) => {
+                                                ::peg::RuleResult::Matched(__pos, ())
+                                            }
+                                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
+                                        }
+                                    }
+                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
                                 }
                             };
-                            let __step_res = {
-                                let __seq_res =
-                                    match __parse_IDENT(__input, __state, __err_state, __pos) {
-                                        ::peg::RuleResult::Matched(pos, _) => {
-                                            ::peg::RuleResult::Matched(pos, ())
-                                        }
-                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
-                                    };
-                                match __seq_res {
-                                    ::peg::RuleResult::Matched(__pos, _) => {
-                                        let __seq_res = match {
-                                            let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "::") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"::\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ;
+                            match __choice_res {
+                                ::peg::RuleResult::Matched(__pos, __value) => {
+                                    ::peg::RuleResult::Matched(__pos, __value)
+                                }
+                                ::peg::RuleResult::Failed => {
+                                    let __seq_res =
+                                        match match ::peg::ParseLiteral::parse_string_literal(
+                                            __input, __pos, "for",
+                                        ) {
+                                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                                let __seq_res = match __parse_rust_ty_params(
+                                                    __input,
+                                                    __state,
+                                                    __err_state,
+                                                    __pos,
+                                                ) {
+                                                    ::peg::RuleResult::Matched(pos, _) => {
+                                                        ::peg::RuleResult::Matched(pos, ())
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                };
+                                                match __seq_res {
+                                                    ::peg::RuleResult::Matched(__pos, _) => {
+                                                        ::peg::RuleResult::Matched(__pos, ())
+                                                    }
+                                                    ::peg::RuleResult::Failed => {
+                                                        ::peg::RuleResult::Failed
+                                                    }
+                                                }
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                __err_state.mark_failure(__pos, "\"for\"");
+                                                ::peg::RuleResult::Failed
+                                            }
+                                        } {
+                                            ::peg::RuleResult::Matched(__newpos, _) => {
+                                                ::peg::RuleResult::Matched(__newpos, ())
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                ::peg::RuleResult::Matched(__pos, ())
+                                            }
+                                        };
+                                    match __seq_res {
+                                        ::peg::RuleResult::Matched(__pos, _) => {
+                                            let __seq_res = match __parse_rust_type(
+                                                __input,
+                                                __state,
+                                                __err_state,
+                                                __pos,
+                                            ) {
+                                                ::peg::RuleResult::Matched(pos, _) => {
+                                                    ::peg::RuleResult::Matched(pos, ())
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            };
                                             match __seq_res {
                                                 ::peg::RuleResult::Matched(__pos, _) => {
                                                     match ::peg::ParseLiteral::parse_string_literal(
-                                                        __input, __pos, "<",
+                                                        __input, __pos, ":",
                                                     ) {
                                                         ::peg::RuleResult::Matched(
                                                             __pos,
@@ -1517,12 +2109,12 @@ pub mod peg {
                                                                     {
                                                                         __pos
                                                                     } else {
-                                                                        let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ",") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\",\"") ; :: peg :: RuleResult :: Failed } } ;
+                                                                        let __sep_res = match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "+") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"+\"") ; :: peg :: RuleResult :: Failed } } ;
                                                                         match __sep_res { :: peg :: RuleResult :: Matched (__newpos , _) => { __newpos } , :: peg :: RuleResult :: Failed => break , }
                                                                     };
                                                                     let __step_res = {
                                                                         let __choice_res = match __parse_LIFETIME (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ;
-                                                                        match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => { let __choice_res = match __parse_rust_type (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => { let __choice_res = match __parse_BRACE_GROUP (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => match __parse_LITERAL (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } } } }
+                                                                        match __choice_res { :: peg :: RuleResult :: Matched (__pos , __value) => :: peg :: RuleResult :: Matched (__pos , __value) , :: peg :: RuleResult :: Failed => { let __seq_res = match match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , "?") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , __val) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\"?\"") ; :: peg :: RuleResult :: Failed } } { :: peg :: RuleResult :: Matched (__newpos , _) => { :: peg :: RuleResult :: Matched (__newpos , ()) } , :: peg :: RuleResult :: Failed => { :: peg :: RuleResult :: Matched (__pos , ()) } , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { { let __seq_res = match __parse_rust_ty_path (__input , __state , __err_state , __pos) { :: peg :: RuleResult :: Matched (pos , _) => :: peg :: RuleResult :: Matched (pos , ()) , :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } ; match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , } } }
                                                                     };
                                                                     match __step_res { :: peg :: RuleResult :: Matched (__newpos , __value) => { __repeat_pos = __newpos ; __repeat_value . push (__value) ; } , :: peg :: RuleResult :: Failed => { break ; } }
                                                                 }
@@ -1535,11 +2127,22 @@ pub mod peg {
                                                                     ::peg::RuleResult::Failed
                                                                 }
                                                             };
-                                                            match __seq_res { :: peg :: RuleResult :: Matched (__pos , _) => { match :: peg :: ParseLiteral :: parse_string_literal (__input , __pos , ">") { :: peg :: RuleResult :: Matched (__pos , __val) => { :: peg :: RuleResult :: Matched (__pos , ()) } :: peg :: RuleResult :: Failed => { __err_state . mark_failure (__pos , "\">\"") ; :: peg :: RuleResult :: Failed } } } :: peg :: RuleResult :: Failed => :: peg :: RuleResult :: Failed , }
+                                                            match __seq_res {
+                                                                ::peg::RuleResult::Matched(
+                                                                    __pos,
+                                                                    _,
+                                                                ) => ::peg::RuleResult::Matched(
+                                                                    __pos,
+                                                                    (),
+                                                                ),
+                                                                ::peg::RuleResult::Failed => {
+                                                                    ::peg::RuleResult::Failed
+                                                                }
+                                                            }
                                                         }
                                                         ::peg::RuleResult::Failed => {
                                                             __err_state
-                                                                .mark_failure(__pos, "\"<\"");
+                                                                .mark_failure(__pos, "\":\"");
                                                             ::peg::RuleResult::Failed
                                                         }
                                                     }
@@ -1548,106 +2151,10 @@ pub mod peg {
                                                     ::peg::RuleResult::Failed
                                                 }
                                             }
-                                        } {
-                                            ::peg::RuleResult::Matched(__newpos, _) => {
-                                                ::peg::RuleResult::Matched(__newpos, ())
-                                            }
-                                            ::peg::RuleResult::Failed => {
-                                                ::peg::RuleResult::Matched(__pos, ())
-                                            }
-                                        };
-                                        match __seq_res {
-                                            ::peg::RuleResult::Matched(__pos, _) => {
-                                                ::peg::RuleResult::Matched(__pos, ())
-                                            }
-                                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
                                         }
+                                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
                                     }
-                                    ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
-                                }
-                            };
-                            match __step_res {
-                                ::peg::RuleResult::Matched(__newpos, __value) => {
-                                    __repeat_pos = __newpos;
-                                    __repeat_value.push(__value);
-                                }
-                                ::peg::RuleResult::Failed => {
-                                    break;
-                                }
-                            }
-                        }
-                        if __repeat_value.len() >= 1 {
-                            ::peg::RuleResult::Matched(__repeat_pos, ())
-                        } else {
-                            ::peg::RuleResult::Failed
-                        }
-                    };
-                    match __seq_res {
-                        ::peg::RuleResult::Matched(__pos, _) => {
-                            ::peg::RuleResult::Matched(__pos, ())
-                        }
-                        ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
-                    }
-                }
-                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
-            }
-        }
-    }
-    fn __parse_rust_ty_params<'input>(
-        __input: &'input Input,
-        __state: &mut ParseState<'input>,
-        __err_state: &mut ::peg::error::ErrorState,
-        __pos: usize,
-    ) -> ::peg::RuleResult<Vec<TokenStream>> {
-        #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
-        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, "<") {
-            ::peg::RuleResult::Matched(__pos, __val) => {
-                let __seq_res = {
-                    let mut __repeat_pos = __pos;
-                    let mut __repeat_value = vec![];
-                    loop {
-                        let __pos = __repeat_pos;
-                        let __pos = if __repeat_value.is_empty() {
-                            __pos
-                        } else {
-                            let __sep_res = match ::peg::ParseLiteral::parse_string_literal(
-                                __input, __pos, ",",
-                            ) {
-                                ::peg::RuleResult::Matched(__pos, __val) => {
-                                    ::peg::RuleResult::Matched(__pos, __val)
-                                }
-                                ::peg::RuleResult::Failed => {
-                                    __err_state.mark_failure(__pos, "\",\"");
-                                    ::peg::RuleResult::Failed
-                                }
-                            };
-                            match __sep_res {
-                                ::peg::RuleResult::Matched(__newpos, _) => __newpos,
-                                ::peg::RuleResult::Failed => break,
-                            }
-                        };
-                        let __step_res = {
-                            let str_start = __pos;
-                            match match __parse_rust_generic_param(
-                                __input,
-                                __state,
-                                __err_state,
-                                __pos,
-                            ) {
-                                ::peg::RuleResult::Matched(pos, _) => {
-                                    ::peg::RuleResult::Matched(pos, ())
-                                }
-                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
-                            } {
-                                ::peg::RuleResult::Matched(__newpos, _) => {
-                                    ::peg::RuleResult::Matched(
-                                        __newpos,
-                                        ::peg::ParseSlice::parse_slice(
-                                            __input, str_start, __newpos,
-                                        ),
-                                    )
                                 }
-                                ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
                             }
                         };
                         match __step_res {
@@ -1660,29 +2167,38 @@ pub mod peg {
                             }
                         }
                     }
-                    if __repeat_value.len() >= 1 {
-                        ::peg::RuleResult::Matched(__repeat_pos, __repeat_value)
-                    } else {
-                        ::peg::RuleResult::Failed
-                    }
+                    ::peg::RuleResult::Matched(__repeat_pos, ())
                 };
                 match __seq_res {
-                    ::peg::RuleResult::Matched(__pos, p) => {
-                        match ::peg::ParseLiteral::parse_string_literal(__input, __pos, ">") {
+                    ::peg::RuleResult::Matched(__pos, _) => {
+                        let __seq_res = match match ::peg::ParseLiteral::parse_string_literal(
+                            __input, __pos, ",",
+                        ) {
                             ::peg::RuleResult::Matched(__pos, __val) => {
-                                ::peg::RuleResult::Matched(__pos, (|| p)())
+                                ::peg::RuleResult::Matched(__pos, __val)
                             }
                             ::peg::RuleResult::Failed => {
-                                __err_state.mark_failure(__pos, "\">\"");
+                                __err_state.mark_failure(__pos, "\",\"");
                                 ::peg::RuleResult::Failed
                             }
+                        } {
+                            ::peg::RuleResult::Matched(__newpos, _) => {
+                                ::peg::RuleResult::Matched(__newpos, ())
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Matched(__pos, ()),
+                        };
+                        match __seq_res {
+                            ::peg::RuleResult::Matched(__pos, _) => {
+                                ::peg::RuleResult::Matched(__pos, ())
+                            }
+                            ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
                         }
                     }
                     ::peg::RuleResult::Failed => ::peg::RuleResult::Failed,
                 }
             }
             ::peg::RuleResult::Failed => {
-                __err_state.mark_failure(__pos, "\"<\"");
+                __err_state.mark_failure(__pos, "\"where\"");
                 ::peg::RuleResult::Failed
             }
         }
@@ -3179,15 +3695,34 @@ pub mod peg {
                                     ::peg::RuleResult::Matched(__pos, __value)
                                 }
                                 ::peg::RuleResult::Failed => {
-                                    match ::peg::ParseLiteral::parse_string_literal(
-                                        __input, __pos, "type",
-                                    ) {
-                                        ::peg::RuleResult::Matched(__pos, __val) => {
-                                            ::peg::RuleResult::Matched(__pos, __val)
+                                    let __choice_res =
+                                        match ::peg::ParseLiteral::parse_string_literal(
+                                            __input, __pos, "type",
+                                        ) {
+                                            ::peg::RuleResult::Matched(__pos, __val) => {
+                                                ::peg::RuleResult::Matched(__pos, __val)
+                                            }
+                                            ::peg::RuleResult::Failed => {
+                                                __err_state.mark_failure(__pos, "\"type\"");
+                                                ::peg::RuleResult::Failed
+                                            }
+                                        };
+                                    match __choice_res {
+                                        ::peg::RuleResult::Matched(__pos, __value) => {
+                                            ::peg::RuleResult::Matched(__pos, __value)
                                         }
                                         ::peg::RuleResult::Failed => {
-                                            __err_state.mark_failure(__pos, "\"type\"");
-                                            ::peg::RuleResult::Failed
+                                            match ::peg::ParseLiteral::parse_string_literal(
+                                                __input, __pos, "where",
+                                            ) {
+                                                ::peg::RuleResult::Matched(__pos, __val) => {
+                                                    ::peg::RuleResult::Matched(__pos, __val)
+                                                }
+                                                ::peg::RuleResult::Failed => {
+                                                    __err_state.mark_failure(__pos, "\"where\"");
+                                                    ::peg::RuleResult::Failed
+                                                }
+                                            }
                                         }
                                     }
                                 }
diff --git a/peg-macros/grammar.rustpeg b/peg-macros/grammar.rustpeg
index 1257617..7fdafdb 100644
--- a/peg-macros/grammar.rustpeg
+++ b/peg-macros/grammar.rustpeg
@@ -10,7 +10,7 @@ pub rule peg_grammar() -> Grammar
         { Grammar { doc, visibility, name, lifetime_params, args, input_type, items } }
 
     rule rust_lifetime_params() -> Vec<TokenStream>
-        = "<" p:(($(LIFETIME())) ++ ",") ">" { p }
+        = "<" p:(($(LIFETIME())) ++ ",") ","? ">" { p }
 
 rule grammar_args() -> Vec<(Ident, TokenStream)>
     = "(" args:((i:IDENT() ":" t:$(rust_type()) { (i, t) })**",") ","? ")" { args }
@@ -23,8 +23,9 @@ rule peg_rule() -> Rule
         / name:IDENT() ty_params:rust_ty_params()? params:rule_params() { (name, ty_params, params) }
       )
       ret_type:("->" t:$(rust_type()) {t})?
+      where_clause:$(rust_where_clause())?
       "=" expr:expression() ";"?
-        { Rule { span, doc, name:header.0, ty_params:header.1, params:header.2, expr, ret_type, visibility, no_eof, cache } }
+        { Rule { span, doc, name:header.0, ty_params:header.1, params:header.2, expr, ret_type, where_clause, visibility, no_eof, cache } }
 
     rule cacheflag() -> Option<Cache> = "#" "[" "cache" "]" {Some(Cache::Simple)} / "#" "[" "cache_left_rec" "]" {Some(Cache::Recursive)} / {None}
 
@@ -35,7 +36,7 @@ rule peg_rule() -> Rule
         / t:$(rust_type()) { RuleParamTy::Rust(t) }
 
     rule rule_params() -> Vec<RuleParam>
-        = "(" params:(name:IDENT() ":" ty:rule_param_ty() { RuleParam { name, ty} }) ** "," ")" { params }
+        = "(" params:(x:(name:IDENT() ":" ty:rule_param_ty() { RuleParam { name, ty} }) ++ "," ","? {x})? ")" { params.unwrap_or_default() }
 
 rule item() -> Item
     = u:rust_use()     { Item::Use(u) }
@@ -48,7 +49,7 @@ rule rust_visibility() -> Option<TokenStream> = $("pub" PAREN_GROUP()?)?
 rule rust_use() -> TokenStream
     = v:$("use" rust_path() (
         "::" "*"
-        / "::" "{" ((IDENT() ("as" IDENT())?) ++ ",") "}"
+        / "::" "{" ((IDENT() ("as" IDENT())?) ++ "," ","?) "}"
         / ("as" IDENT())?
     ) ";") { v.to_owned() }
 
@@ -58,16 +59,22 @@ rule rust_path()
 rule rust_type()
     = BRACKET_GROUP()
     / "&" LIFETIME()? "mut"? rust_type()
-    / "dyn" rust_type()
-    / "impl" rust_type()
-    / "(" rust_type() ** "," ")"
-    / rust_ty_path()
+    / "dyn" rust_type() ++ "+"
+    / "impl" rust_type() ++ "+"
+    / "(" (rust_type() ++ "," ","?)? ")"
+    / ("<" rust_type() ("as" rust_ty_path())? ">")? rust_ty_path()
 
 rule rust_ty_path()
-    = "::"? (IDENT() ("::"? "<" (LIFETIME() / rust_type() / BRACE_GROUP() / LITERAL()) ++ "," ">")?) ++ "::"
+    = "::"? (IDENT() ("::"? ("<" (LIFETIME() / rust_type() / BRACE_GROUP() / LITERAL()) ++ "," ","? ">" / PAREN_GROUP() ("->" rust_type())?))?) ++ "::"
 
 rule rust_ty_params() -> Vec<TokenStream>
-    = "<" p:($(rust_generic_param()) ++ ",") ">" { p }
+    = "<" p:($(rust_generic_param()) ++ ",") ","? ">" { p }
+
+rule rust_where_clause()
+    = "where" (
+        LIFETIME() (":" LIFETIME() ++ "+")?
+        / ("for" rust_ty_params())? rust_type() ":" (LIFETIME() / "?"? rust_ty_path()) ++ "+"
+    ) ** "," ","?
 
 rule rust_generic_param()
     = LIFETIME() (":" LIFETIME() ++ "+")?
@@ -147,7 +154,7 @@ rule precedence_op() -> PrecedenceOperator
   { PrecedenceOperator{ span, elements, action } }
 
 rule sp() -> Span = ##next_span()
-rule KEYWORD() = "pub" / "rule" / "use" / "type"
+rule KEYWORD() = "pub" / "rule" / "use" / "type" / "where"
 rule IDENT() -> Ident = !KEYWORD() i:##ident() {i}
 rule LITERAL() -> Literal = ##literal()
 rule PAREN_GROUP()   -> Group = ##group(Delimiter::Parenthesis)
diff --git a/peg-macros/translate.rs b/peg-macros/translate.rs
index 3afbe18..6b5c659 100644
--- a/peg-macros/translate.rs
+++ b/peg-macros/translate.rs
@@ -215,6 +215,7 @@ fn compile_rule(context: &Context, rule: &Rule) -> TokenStream {
     let name = format_ident!("__parse_{}", rule.name, span = span);
     let ret_ty = rule.ret_type.clone().unwrap_or_else(|| quote!(()));
     let ty_params = ty_params_slice(&rule.ty_params);
+    let where_clause = rule.where_clause.as_ref().into_iter();
 
     let Context {
         input_ty,
@@ -319,7 +320,14 @@ fn compile_rule(context: &Context, rule: &Rule) -> TokenStream {
     };
 
     quote_spanned! { span =>
-        fn #name<'input #(, #grammar_lifetime_params)* #(, #ty_params)*>(__input: #input_ty, __state: #parse_state_ty, __err_state: &mut ::peg::error::ErrorState, __pos: usize #extra_args_def #(, #rule_params)*) -> ::peg::RuleResult<#ret_ty> {
+        fn #name<'input #(, #grammar_lifetime_params)* #(, #ty_params)*>(
+            __input: #input_ty,
+            __state: #parse_state_ty,
+            __err_state: &mut ::peg::error::ErrorState,
+            __pos: usize #extra_args_def #(, #rule_params)*,
+        ) -> ::peg::RuleResult<#ret_ty>
+        #(#where_clause)*
+        {
             #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
             #fn_body
         }
@@ -340,6 +348,7 @@ fn compile_rule_export(context: &Context, rule: &Rule) -> TokenStream {
     let ret_ty = rule.ret_type.clone().unwrap_or_else(|| quote!(()));
     let parse_fn = format_ident!("__parse_{}", rule.name.to_string(), span = name.span());
     let ty_params = ty_params_slice(&rule.ty_params);
+    let where_clause = rule.where_clause.as_ref().into_iter();
     let rule_params = rule_params_list(context, rule);
     let rule_params_call: Vec<TokenStream> = rule
         .params
@@ -369,7 +378,14 @@ fn compile_rule_export(context: &Context, rule: &Rule) -> TokenStream {
 
     quote_spanned! { span =>
         #doc
-        #visibility fn #name<'input #(, #grammar_lifetime_params)* #(, #ty_params)*>(__input: #input_ty #extra_args_def #(, #rule_params)*) -> ::core::result::Result<#ret_ty, ::peg::error::ParseError<PositionRepr<#(#grammar_lifetime_params),*>>> {
+        #visibility fn #name<'input #(, #grammar_lifetime_params)* #(, #ty_params)*>(
+            __input: #input_ty #extra_args_def #(, #rule_params)*
+        ) -> ::core::result::Result<
+            #ret_ty,
+            ::peg::error::ParseError<PositionRepr<#(#grammar_lifetime_params),*>>
+        >
+        #(#where_clause)*
+        {
             #![allow(non_snake_case, unused)]
 
             let mut __err_state = ::peg::error::ErrorState::new(::peg::Parse::start(__input));


Test patch:
diff --git a/tests/run-pass/generic_fn_traits.rs b/tests/run-pass/generic_fn_traits.rs
new file mode 100644
index 0000000..f9d88e8
--- /dev/null
+++ b/tests/run-pass/generic_fn_traits.rs
@@ -0,0 +1,21 @@
+extern crate peg;
+
+peg::parser!(
+grammar parser() for str {
+    pub rule foo<F: Fn(&str) -> u32 + Copy>(f: F) -> u32
+        = s:$(['0'..='9']+) { f(s) }
+    pub rule bar(f: impl Fn(&str) -> u32 + Copy,) -> u32
+        = s:$(['0'..='9']+) { f(s) }
+    pub rule baz(f: fn(&str) -> u32) -> u32
+        = s:$(['0'..='9']+) { f(s) }
+}
+);
+
+fn main() {
+    let n = parser::foo("123", |s| s.parse().unwrap()).unwrap();
+    assert_eq!(n, 123);
+    let n = parser::bar("123", |s| s.parse().unwrap()).unwrap();
+    assert_eq!(n, 123);
+    let n = parser::baz("123", |s| s.parse().unwrap()).unwrap();
+    assert_eq!(n, 123);
+}
diff --git a/tests/run-pass/rule_where_clause.rs b/tests/run-pass/rule_where_clause.rs
new file mode 100644
index 0000000..69fea04
--- /dev/null
+++ b/tests/run-pass/rule_where_clause.rs
@@ -0,0 +1,27 @@
+extern crate peg;
+use std::{
+    str::FromStr,
+    fmt::Debug,
+};
+
+peg::parser!(
+grammar parser() for str {
+    use std::cell::Cell;
+    pub rule nums<C, T>() -> C
+    where C: Default + Extend<T>,
+          T: FromStr,
+          <T as FromStr>::Err: Debug,
+        = c:({ Cell::new(C::default()) })
+          (ch:$(['0'..='9']) {
+              let mut mutc = c.take();
+              mutc.extend(Some(ch.parse::<T>().unwrap()));
+              c.set(mutc);
+          })+
+          { c.take() }
+}
+);
+
+fn main() {
+    assert_eq!(parser::nums::<Vec<u8>, u8>("3729"), Ok(vec![3, 7, 2, 9]));
+}
+