syn icon indicating copy to clipboard operation
syn copied to clipboard

PatOr doesn't round-trip

Open alercah opened this issue 4 years ago • 1 comments

I am trying to write some code which parses patterns like an if let expression does, and I discovered that it cannot parse |-patterns.

This appear's to be because most parsing of |-patterns is handled externally to parsing the Pat itself. As a result, PatOr does not round-trip:

    #[test]
    pub fn test_parse() {
        let e: syn::Expr = syn::parse_str(&"if let | a = () {}").unwrap();
        if let syn::Expr::If(syn::ExprIf { cond: e, .. }) = e {
            if let syn::Expr::Let(syn::ExprLet { pat, .. }) = *e {
                let mut ts = pm2::TokenStream::new();
                pat.to_tokens(&mut ts);
                let res: syn::Pat = syn::parse2(ts).unwrap();
                println!("{:?}", res);
            } else {
                panic!("no if let xpr")
            }
        } else {
            panic!("no if let expr")
        }
    }

The PatOr here is | a, but trying to parse this again as a pattern fails. The fact that it is a leading | doesn't matter; a | a fails too.

alercah avatar Nov 14 '20 22:11 alercah

I have a similar problem.

I want to reuse some parsing logic of ExprForLoop, however it parses Pat with pat::parsing::multi_pat_with_leading_vert which is not public

https://github.com/dtolnay/syn/blob/0bd6d57baa589331e0306d76fae42324aa13039c/src/expr.rs#L2084

https://github.com/dtolnay/syn/blob/0bd6d57baa589331e0306d76fae42324aa13039c/src/lib.rs#L418

While Parse impl for Pat doesn't handle PatOr like pat::parsing::multi_pat_with_leading_vert do so they are different.

Any reason for not export the pat mod?

yume-chan avatar Feb 26 '21 18:02 yume-chan

As of syn 2, this works by doing let res = Pat::parse_multi_with_leading_vert.parse2(ts).unwrap();.

dtolnay avatar Mar 18 '23 22:03 dtolnay