dtolnay / syn

Parser for Rust source code
Apache License 2.0
2.88k stars 311 forks source link

Unsuccessful parsing of ExprRange consumes a token #1612

Closed MauriceKayser closed 7 months ago

MauriceKayser commented 7 months ago

It seems like unsuccessfully parsing a syn::ExprRange causes a literal to be swallowed.

In this playground code I had expected to get an Ok(Single(LitChar { token: 'a' })) instead of an Err(Error("unexpected end of input, expected character literal")) from the call to parse2.

extern crate quote; // 1.0.35
extern crate syn; // 2.0.57

fn main() {
    println!("{:?}", syn::parse2::<RangeOrSingle>(quote::quote!('a')));
}

#[allow(dead_code)]
#[derive(Debug)]
enum RangeOrSingle {
    Range(syn::ExprRange),
    Single(syn::LitChar),
}

impl syn::parse::Parse for RangeOrSingle {
    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
        Ok(if let Ok(r) = input.parse() {
            Self::Range(r)
        } else {
            Self::Single(input.parse()?)
        })
    }
}

When trying with quote!('a' 'b') instead I get Ok(Single(LitChar { token: 'b' })).

Not sure if I am misusing the API and this is intended behaviour, or if I hit a bug?

dtolnay commented 7 months ago

I think this is all right as currently implemented. We don't guarantee a particular cursor position after errors.