Rust 2019: Compiler, Community, and Const Generics.

Introduction

This article is a repsponse to the call for 2019 wishlist blog posts for the Rust programming language.

A Personal Rusty Utopia

Before outlining what I think the Rust project should work on this year, I would like to be a bit less formal and list what I personally would love. In order of priority:

Async-await syntax and broad library support for futures 0.3. A fast, stable, async rocket-like batteries-included web framework, with out of the box support for database access. Faster compile times. Faster. Freaking. Compile times.

The promise that Rust holds for me (along with strong safety/correctness guarantees that IMO it already delivers on) is high developer productivity combined with best-in-class runtime performance. At the moment I can have one (rocket) or the other (actix/warp/tower-web). In 2019 I want both!

While I think IDE support is important for the ecosystem, I’m personally relatively happy to make do without for the time being. Ditto with language features like Generic Associated Types and Specialization.

Rust in 2021: Maturity

I think that Rust should aim to make 2021 about Maturity (although as mentioned below, I’m skeptical of the idea of another marketing push like Rust 2018). For me, this is all about “filling in the gaps”. This means language features like GATs. And standard library things like SIMD support. In 2021 there shouldn’t be too many areas where we need to tell people “it’s not stable yet”.

The library ecosystem should see a similar maturation. More 1.0 libraries in key areas, and a wider variety of libraries covering more niche usecases. Established libraries that have already released a 1.0 version might be looking at releasing there 2.0 or 3.0 versions.

It should also mark a slowing of new feature development. I don’t think we should ever completely stop (I think there’s a lot of potentially interesting research to be done around self-referential structs and really pushing the borrow checker for example), but the pace at which big new features are released should slow and be less disruptive to the ecosystem.

Compiler. Compiler. Compiler.

I believe that in 2019, the Rust Project should focus on improvements to compiler implementation. This is similar message to other posts that have called for a fallow year, or improving on what we have.

Compile Times. Especially incremental debug compile times.

I believe that compile times are by far the biggest issue with Rust at the moment. This issue may be masked by the fact that many Rust developers come from a C++ background, and C++ has absolutely abysmal compile times. But several projects like Go, D, Delphi, etc have shown that it is possible to have fast compile times in an optimised compile-to-native language. Specific suggestions for work areas:

End-to-End Incremental Compilation Incremental compiltion is already a big step in the right direction, but it doesn’t currently work for everything. A big area in which it doesn’t currently work is macro expansion. This is a big deal because macros are everywhere in Rust (e.g. serde).

MIR optimisation passes for better LLVM IR Supposedly one of the reasons that LLVM is so slow on Rust code is that the LLVM IR that Rust generates is bloated and innefficient. We could improve this by running some optimisation on MIR in rustc itself. As a bonus, these optimisations would apply to other backends.

Experimental Cranelift backend Even with optimising the IR, LLVM is likely to be slow. It simply isn’t designed to be fast. Therefore, an alternative backend is a must for the best performance. D and Go have proved this approach with great success.

LLD for faster linking I’ve seen reports of debug builds going from 6 seconds to 1.5 second by switching to LLD. That may not seems like much, but IMO that’s a pretty significant for small projects. Edit-Compile-Debug latency is important.

Niko Matsakis (I’m a different Nico!) has put a lot of ideas in this thread which is continued here, which I would like to draw attention to as I think that they should be a priority for this year.

Language Server / IDE Suppport

Going hand in hand with compilation speed is IDE support (syntax checking, code completions, etc). I come from a JavaScript background, so I probably don’t miss IDE support as much as some people (JavaScript doesnt have much!). But even I have noticed that the Rust plugins for my VS Code are slow, often crashy. Autocomplete is so bad that I usually ignore it, preferring to refer to the Rust docs in a browser tab.

My impression is that a Libsyntax2/Rust-Analyzer based approach is much more likely to lead to something useful than the hybrid racer/rustc approach taken by the current RLS. This will require rustc to be much faster than it currently is, but as I have written above, I believe that this should be a first-class goal in and of itself anyway. If taking this kind of approach means that IDE support takes a little longer to come to fruition, then I think that is price worth paying. Better to have a solid foundation than a something half-baked sooner.

The key features I would like my IDE to have:

Fast error- and warning-underlining for compiler errors/warnings.

Type lookup (hover over a variable to see the inferred type).

Ideally this should link to the docs for that type.

Ideally this should link to the docs for that type. Autocomplete for types, methods, etc.

Compiler Refactors (Chalk, Polonious, etc)

There are a few big refactors that have been a work-in-progress for a while, and I feel like it would be a good idea to prioritise finishing and merging these. If this year is to be a slower one on the language-feature front, and we are to focus on the compiler implementation then now seems like a good time for this work. And it should put us in a good position for feature development (and hopefully perfomance improvements) going forwards.

Community Improvements

I should preface this section by saying that I think Rust has one of the best communities of any programming language or framework (or any organisation actually). Props to the core rust team for making this the case. Having said that, this is an area where there is always room for improvement, and I would like to highlight a couple of areas where I think we could do better.

No more coordinated marketing around editions

I believe that coordinating a marketing milestone with the release of a new edition (breaking changes) like was done for the Rust 2018 release was a mistake. I didn’t forsee this in advance, but in retrospect it is obvious to me: in Rust the big features don’t necessarily land in breaking versions, and breaking versions don’t necessarily include big feautures. This makes an edition one of the worst times for a marketing push!

Additionally, I feel like the time pressure was harmful to the community process. Thankfully async/await got postponed and wasn’t rushed to meet the deadline. But I feel like the things like the website were rushed unnecesarily. And this stands out in contrast to the usual “release often so we don’t have to rush features for releases” policy.

I agree with this comment on reddit. Specifically, I believe that:

Editions should be “when it is ready” , not tied to a specific release date.

, not tied to a specific release date. Marketing milestones should be separate to the Edition mechanism. There was for example no real reason to release the new website along with the Rust 2018 release. That could have been it’s own release in a few months time, generating extra buzz.

There was for example no real reason to release the new website along with the Rust 2018 release. That could have been it’s own release in a few months time, generating extra buzz. We can celebrate/market major “minor” releases For examle, Rust 1.15 was a huge release with custom derives stablising. That would have been a good point to do a marketing push. Rust 1.31 was not.

An RFC and implementation tracker

I think I’m not the only one who finds it difficult to keep track of everything that is going on. There is so much being worked on at once, and it’s all tracked through GitHub issue of which there are thousands. Other projects have dedicated (custom) tracker websites which help to manage this complexity and information overload.

For example Chrome Status and Edge Platform Status. If we could have something like that also integrated with GitHub, and provided a stable place to allow things to be tracked all the way from proposal to stablisation, that would be wonderful. It could also provide a good means by which to introduce a stages RFC process…

Stablisation and release predictions

Brian Anderson (brson) used to maintain a fantastic Rust Release Milestone Predictions document. It’s a bit out of date now and only shows features that landed in previous releases, but back when it was maintained, it used to show predictions for what would be released 2-3 releases ahead. And then there was the “Horizon” category of features that didn’t have a useful predicted release date, but were actively being worked on. These would be updated/revised as things changed, and showing here was never a guarantee that something would ship in a given release, but it was really nice to be able to see roughly what kind of dates the core team had in mind for certain features.

I wonder whether we could revive this page, making it a bit more official (perhaps as part of the RFC tracker, but even where it is would be fine). I think this would help a lot with the “people feeling like they can’t kee track of everything problem”.

The last time I linked someone to this, someone gifted me Reddit gold!

Release notes For beta releases

I think we should be posting release notes to the rust blog for beta releases as well as stable ones. This provides a couple of benefits:

Visibility of soon-to-be-stablised features. There were a few stablisations in the last few weeks that seemed to catch people out. For example, impl trait in argument position, and ? in main using Debug rather than Display . publishing release notes for beta releases would provide visibility for these new features before we have committed to them being stable, and allow for last-minute changes or postponement if desired by the community.

It would encourage people to use betas Not many people use the Beta releases at the moment. Now that’s partly because it’s only 6 weeks until the release becomes stable, so people can just wait. But I’m betting it doesn’t hel that the only way to discover which features are in the latest beta is via reddit.

Some notable examples of projects that do both stable and beta release notes are Atom Editor and Chrome.

Language Features

I’ve purposely put this section at the bottom, because I think that this year the focus ought to be on the other stuff. However, I think there are some high-priority language features that ought to be worked on.

Const Generics

Const generics are making good progress (tracking issue latest PR). They fit well into the overall story of compiler refactorings that I’m advocating. They are also a really big deal for settling on a stable API for a number of foundation libraries. Things like ndarray, but also simpler libraries like SmallVec/ArrayVec.

Enough said. I think everyone is on board with this anyway.

Async/Await

I’m actually less fussed by this feature than some people are, even though my use cases for Rust (web services) fit squarely in the area where this feature is useful. The blockers for async web for me are more around library maturity (futures/tokio and everything that builds on top of them): working with futures directly is a little awkward, but it’s not really a problem.

However, seeing as most of the work left for this feature seems to around stablising the standard library futures anyway, I would like to see it released. It will definitely be a big quality of life improvement. My caution to the Rust community is to avoid relying on it too much. Manually writing/combinating futures should be supported too where possible.

Remaining Proc Macro features

These seem to be the main remaining things that are blocking stable Rocket. I’m not quite sure how much effort is required to stablise them, but if it’s not too much effort then I think it ought to be done sooner rather than later. My impression is that this would also remove the need for workarounds that are currently being used to emulate some of these features with what is currently available, which would presumbly be another compile time win.

Library additions

Error trait rework

Error handling in Rust is generally pretty good (so good that other languages seem to be falling over themselves to copy it). But I still think this is somewhere where the story isn’t really settled. I’d like to see the improvements to the Error trait prioritised. Beyond that, it may just be a matter of experimenting with different approaches and libraries until we find what sticks.

I recently discovered the custom_error crate which looks like it solves quite a lot of problems. But I haven’t had the opportunity to try it yet!

Officially blessed libraries (consider shipping with Rust)

I think that Rust’s strategy of keeping as much as possible out of the standard library is a good one. However, I think that being included in the stanard library has two benefits:

The standard library comes with stability guarantees.

The standard library comes by default, is easy to find, doesn’t need to be downloaded, etc.