[rust-dev] Syntax sugar: Vec Rc RefCell Box Foo -> Vec<Rc<RefCell<Box<Foo>>>>

Benjamin Herr ben at 0x539.de
Sat Jun 28 15:48:46 PDT 2014


So, I've been vaguely concerned that types in a less sigil-heavy Rust
inevitably devolve into what some call "spikey lisp", and tried to come
up with some more lightweight syntax. Of course, just removing syntax is
the easiest way to make it weigh less, and it seems like the following
doesn't actually break the grammar dramatically (only some macros!):

In parsing a path, if a path segment is immediately followed by an
identifier, start parsing another type right away and use it as the only
element of the type parameter list for the current path segment.

This is fairly limited:

* It won't work for absolute paths as type parameters
  (since they'll look like just another path segment)
* It also doesn't work for non-path types in type parameter lists
* It doesn't simplify multiple type parameters

I think that's okay, since it's a simplification that applies well to a
lot of simple cases, and might still reduce the total depth of `<`, `>`
nesting in more complicated cases.

So, for example, the following desugarings would apply:

       Vec String
    => Vec<String>

       Arc RWLock Vec f64
    => Arc<RWLock<Vec<f64>>>

       Arc Exclusive Vec Box Buffer T
    => Arc<Exclusive<Vec<Box<Buffer<T>>>>>         // from libsync

       RefCell DefIdMap Rc Vec Rc TraitRef
    => RefCell<DefIdMap<Rc<Vec<Rc<TraitRef>>>>>    // from librustc
    
       HashMap<Vec String, Vec Rc Cell int>
    => HashMap<Vec<String>, Vec<Rc<Cell<int>>>>

       Add<Complex T, Complex T>
    => Add<Complex<T>, Complex<T>>
    
       std::mem::size_of RefCell String()          // maybe a bit much?
    => std::mem::size_of::<RefCell<String>>())

I've patched that into libsyntax and `make check` passes...

... after changing some macros, since it basically means that adjacent
identifiers parse as a single type (or expression, if we omit `::<>`
too) and some macros try to match `($x:ty fake_keyword_ident ...)`, or
have a case for `($x:expr)` and another for `(fake_keyword $x:expr)`, or
just `($t:ty)*`. Seems like just chomping down on all adjacent
identifiers makes the parser pretty aggressive...

Yeah, okay, I don't know if this is really a good idea, and it's
probably not RFC-worthy at this point, but imo it does make the syntax a
bit easier on the eyes, and I think that's something we ought to look at
at some point.



More information about the Rust-dev mailing list