1. Quick and dirty checklist to update syn 0.11.x to syn 0.12

    - Tags: gnome, rust

    Today I ported gnome-class from version 0.11 of the syn crate to version 0.12. syn is a somewhat esoteric crate that you use to parse Rust code... from a stream of tokens... from within the implementation of a procedural macro. Gnome-class implements a mini-language inside your own Rust code, and so it needs to parse Rust!

    The API of syn has changed a lot, which is kind of a pain in the ass — but the new API seems on the road to stabilization, and is nicer indeed.

    Here is a quick list of things I had to change in gnome-class to upgrade its version of syn.

    There is no extern crate synom anymore. You can use syn::synom now.

    extern crate synom;    ->   use syn::synom;
    

    SynomBuffer is now TokenBuffer:

    synom::SynomBuffer  ->  syn::buffer:TokenBuffer
    

    PResult, the result of Synom::parse(), now has the tuple's arguments reversed:

    - pub type PResult<'a, O> = Result<(Cursor<'a>, O), ParseError>;
    + pub type PResult<'a, O> = Result<(O, Cursor<'a>), ParseError>;
    
    // therefore:
    
    impl Synom for MyThing { ... }
    
    let x = MyThing::parse(...).unwrap().1;   ->  let x = MyThing::parse(...).unwrap().0;
    

    The language tokens like synom::tokens::Amp, and keywords like synom::tokens::Type, are easier to use now. There is a Token! macro which you can use in type definitions, instead of having to remember the particular name of each token type:

    synom::tokens::Amp  ->  Token!(&)
    
    synom::tokens::For  ->  Token!(for)
    

    And for the corresponding values when matching:

    syn!(tokens::Colon)  ->  punct!(:)
    
    syn!(tokens::Type)   ->  keyword!(type)
    

    And to instantiate them for quoting/spanning:

    -     tokens::Comma::default().to_tokens(tokens);
    +     Token!(,)([Span::def_site()]).to_tokens(tokens);
    

    (OK, that one wasn't nicer after all.)

    To the get string for an Ident:

    ident.sym.as_str()  ->  ident.as_ref()
    

    There is no Delimited anymore; instead there is a Punctuated struct. My diff has this:

    -  inputs: parens!(call!(Delimited::<MyThing, tokens::Comma>::parse_terminated)) >>
    +  inputs: parens!(syn!(Punctuated<MyThing, Token!(,)>)) >>
    

    There is no syn::Mutability anymore; now it's an Option<token>, so basically

    syn::Mutability  ->  Option<Token![mut]>
    

    which I guess lets you refer to the span of the original mut token if you need.

    Some things changed names:

    TypeTup { tys, .. }  ->  TypeTuple { elems, .. }
    
    PatIdent {                          ->  PatIdent {
        mode: BindingMode(Mutability)           by_ref: Option<Token!(ref)>,
                                                mutability: Option<Token![mut]>,
        ident: Ident,                           ident: Ident,
        subpat: ...,                            subpat: Option<(Token![@], Box<Pat>)>,
        at_token: ...,                      }
    }
    
    TypeParen.ty  ->  TypeParen.elem   (and others like this, too)
    

    (I don't know everything that changed names; gnome-class doesn't use all the syn types yet; these are just the ones I've run into.)

    This new syn is much better at acknowledging the fine points of macro hygiene. The examples directory is particularly instructive; it shows how to properly span generated code vs. original code, so compiler error messages are nice. I need to write something about macro hygiene at some point.

Page 76 of 105 (previous) (next)