Its that time of year again and its been exciting watching the language grow over this past year! Looking back through the Rust releases for the entire year, starting with 1.32.0 there’s been some fantastic progress, which is pretty easy to forget! So why not start with a bit of a recap of some of the big things from each release:

? as a macro-repetition operator

as a macro-repetition operator The literal macro_rules! fragment specifier

macro_rules! fragment specifier Self as a constructor and pattern for tuple and unit structs, along with being allowed in type definitions

as a constructor and pattern for tuple and unit structs, along with being allowed in type definitions Stabilization of all of the numeric to_{be,le}_bytes and from_{be,le}_bytes conversions

and conversions The dbg! macro was stabilized

Multiple patterns in if let and while let s, along with warn-by-default irrefutable patterns

and s, along with warn-by-default irrefutable patterns Importing items (especially traits!) as _

More non- Self method receiver types: Rc , Arc , Pin

method receiver types: , , Quite a few methods/functions made const

Pin API stabilized!

Atomic integer types stabilized

Try{From,Into} stabilized

stabilized Alternative registries stabilized in cargo

Box<dyn Fn{Mut,Once}> now implements the respective trait

now implements the respective trait The contains method on range types stabilized

Non-Lexical Lifetimes enabled on the 2015 edition

std ’s HashMap implementation replaced with hashbrown::HashMap which gives a pretty significant performance improvement with no user code change necessary!

’s implementation replaced with which gives a pretty significant performance improvement with no user code change necessary! alloc crate stabilized

crate stabilized MaybeUninit stabilized

stabilized Future trait stabilized along with the task module

_ can now be used as an identifier for constants

can now be used as an identifier for constants Profile-Guided Optimizations flag made available

Trait objects without dyn prefix now warn-by-default

Pipelined compilation enabled!

Pointer type cast methods stabilized

methods stabilized Some undefined behavior lints around mem::{uninitialized, zeroed}

And probably one of the most anticipated releases to date:

async / .await stabilized, allowing for ergonomic asynchronous code on stable!

/ stabilized, allowing for ergonomic asynchronous code on stable! Shared references allowed in bind-by-move pattern guards stabilized!

Wow, what a year! There’s only one release left in this calendar year, but it’ll be tough to beat the hype around 1.39 ;)

A lot of other things happened over the past year that didn’t quite get the attention that some of the things that made the release notes did, namely const_generics has made quite the progress! What used to ICE the compiler very frequently now doesn’t do it quite as often, and there’s some great ergonomics being made already with them, such as trait implementations for all array sizes (even if they are still gated by LengthAtMost32 , and remember, never call my_array.into_iter() as it is right now folks!)

So I think Rust 2020 should be a similar story to Rust 2019, and other people seem to agree: make great progress on the work we’ve started and ship some awesome new features that make the language even better to use.

But, I’d also like to take some time to mention something that doesn’t quite get enough love in my opinion: the ergonomics around proc macros. Proc macros play a huge role in the Rust ecosystem today, the biggest probably being derive proc macros. They help reduce boilerplate and can make some rough edges around the language a bit more bearable. I think that last part is particularly important – if something that’s usually very tedious or sensitive to do by hand, having a proc macro available to do it is a massive boon! Though, as you may know, proc macros aren’t all sunshine and rainbows themselves. There’s some pretty major pain points around them:

Proc macros require their own crate. This is a huge ergonomic issue and it makes creating new proc macros a nuisance at best. No parsing library that ships with the language It feels like a bit of a missed opportunity to me to not have included a parsing library for users of the language to use out of the box – instead proc macros have to deal with the 3 Crates of the Compile Time Apocalypse™: syn , quote , proc-macro2 (okay maybe that’s a little harsh, but syn takes a significant amount of time to compile!) Don’t get me wrong, there’s nothing inherently bad about relying on a 3rd party crate to parse a language, but it ends up feeling like a chore to set up a proc macro because of this sometimes. Compile times To run off of my above sentiment, proc macros can significantly increase the compile time of projects, mainly because of the dependency all of them have on syn . It also turns out that proc macros are not pipelined at all with their dependencies as it stands right now. proc_macro_hygiene The proc_macro_hygiene feature is the last(!) feature that is preventing rocket from hitting stable Rust now in its current form. Other libraries definitely would make use of this as well, as can be seen from the over 1 million all-time downloads on the proc-macro-hack crate. Its a major missing piece of the proc macro puzzle, in my opinion, and it would be great to see some progress on it. Though as of the time of writing, the pull request that enables Fn-like and attribute proc macros to generate macro_rules! items was merged 26 days ago.

I’m sure there’s more issues that will come up and/or that I’m not aware of, but those are definitely some of the biggest problems proc macros face today, in my opinion, and moving the ergonomics of them forward would at least help smooth off some edges with the language as they stand today.

Thanks for reading and happy soon-to-be 2020 :)