null pointer

Ideas expressed here are nobody's.

Rust 2020 🦀

Every year I think of writing a “Rust 20xx”1 post, and I never do, but this year I've decided to power through the procrastination, I'm also on a 5 hour flight with no Wi-Fi, so this will at least provide me with some form of entertainment!

Since I'm blessed enough to work full-time using Rust2 I end up having two separate sets of goals for Rust, one from the point of view of Standard Cognition (Sc) as a company that is committed to Rust, and another as someone who likes to work on projects in Rust in his free time. I'll separate both, and try to not jumble my wishes for Standard and my personal ones.

Standard Cognition & Rust in 2020

One of our main annoyances at Sc is the fact that we are still on the nightly compiler, mostly due to a number of features that we couldn't build our product without, but that still haven't seen their way through to stabilization. Namely, these are:

1
rg --no-filename '^#!\[feature(.+)]' | sort -u
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// https://github.com/rust-lang/rust/issues/52662
#![feature(associated_type_bounds)]

// https://github.com/rust-lang/rust/issues/62290
#![feature(async_closure)]

// https://github.com/rust-lang/rust/issues/61356
#![feature(bound_cloned)]

// We use this for printing the type name in generic errors,
// an alternative has been recently stabilized, IIRC
#![feature(core_intrinsics)]

// https://github.com/rust-lang/rust/issues/43244
#![feature(drain_filter)]

// https://github.com/rust-lang/rust/issues/44732
#![feature(external_doc)]

// https://github.com/rust-lang/rust/issues/29625
#![feature(fn_traits)]

// https://github.com/rust-lang/rust/issues/56167
#![feature(hash_raw_entry)]

// https://github.com/rust-lang/rust/issues/53485
#![feature(is_sorted)]

// https://github.com/rust-lang/rust/issues/35121
#![feature(never_type)]

// https://github.com/rust-lang/rust/issues/13231
#![feature(optin_builtin_traits)]

// https://github.com/rust-lang/rust/issues/60258
#![feature(option_flattening)]

// https://github.com/rust-lang/rust/issues/53268
#![feature(result_map_or_else)]

// https://github.com/rust-lang/rust/issues/31844
#![feature(specialization)]

// https://github.com/rust-lang/rust/issues/42168
#![feature(step_trait)]

// https://github.com/rust-lang/rust/issues/41517
#![feature(trait_alias)]

// https://github.com/rust-lang/rust/issues/42327
#![feature(try_trait)]

// https://github.com/rust-lang/rust/issues/29625
#![feature(unboxed_closures)]

I'm fairly sure a couple of these have only recently been stabilized, but we only bump the compiler once in a blue moon since it's usually a bit of a chore. Most notably, the never_type was just stabilized!

There are some other features that we don't use, but only because the path for them to be stabilized is so unclear and we didn't want to further commit to using unstable features. The big ones here, where stabilization would be a revolution in our codebase are const generics and GATs. My understanding is that for the former we would ideally achieve lazy normalization inside the compiler, and that there's still quite a bit of work ahead of us for that. For GATs I'm not quite sure which yaks will need to be shaven.

Another thing we'd like to see at Sc is a number of improvements to Cargo, some things that come to mind are:

  1. Constraining build.rs
    1. We'd like for it to not have network access, and possibly only limited filesystem access. Right now the build script has unlimited power, which is really no good.
  2. Better dependency handling
    1. There are a number of annoyances in Cargo relating to dependencies. The primary one being that if a crate exposes both a binary and a library (c.f. clap + bindgen, etc) but you only use the library portion you must still download and build all the binary-only dependencies. Another issue is that build-dependencies share the same resolution graph with dev-dependencies and dependencies which causes issues in settings where the target doesn't support a build dependency even though only the host needs it (for building.)
  3. Better integration with other build systems
    1. Cargo is pretty great as a standalone build tool for Rust, but it's pretty bad at integrating with anything else. At Sc we use Nix everywhere, and the intgration with Rust has been painful, though there are promising projects like crate2nix.

The last big thing we're excited about is async/await, here are some of the things we're still missing from it:

  1. Streams
    1. Ideally we'd model a lot of our workloads with streams, so we'd love to see them stabilized and well-supported.
  2. Stable ecosystem
    1. It feels like Tokio has been around since forever without reaching 1.0 status, we'd like to see more proactiveness around stabilization; async-std has been a positive force in this space.
    2. On a separate note, the Rust ecosystem as a whole has started abusing semver in weird ways, such as versioning crates to the liking of `0.1.0alpha7 as opposed to just bumping the revision. Let's bump revisions in the 0.x range quickly and aim for stabilization; having to tag a 2.0 some day isn't the end of the world.
  3. Clear performance metrics
    1. As the ecosystem becomes increasingly diverse it'll become necessary for there to be a “unified measuring stick” so that performance can be reasonably compared.

As a final note on Sc, I think it's easy for us who are heavily invested and deeply embedded into Rust to miss the forest for the trees and think that the lack of this or that feature, or that the existence of one or another wart in the ecosystem is a much bigger deal than it really is. Asking my coworkers who learned Rust on the job and transitioned from C++ and Java the feedback is overwhelmingly positive, even about the ‘wartiest’ parts of the ecosystem. I think Rust has achieved a lot more than we give ourselves credit for.

Bernardo & Rust in 2020

While most of my desires for Rust align with Sc's there are a few things that are strictly personal wishes, namely:

  1. Rust 2021
    1. I think we should have an edition in 2021, and if the 2018 edition taught us anything it's that we should take more time in the edition process, I think two years instead of one will be a huge win.
  2. Better embedded support
    1. It's a bit silly that we still need to use cargo-xbuild (fka. xargo) it's about time Cargo has first-class support for these use-cases.
  3. Stable ABI
  4. Lazy normalization
  5. Simple ways to unify CLI options and config
    1. Right now it's simple to create a CLI app with rust using structopt, and it's also trivial to define and source a TOML config file, but combining both is not nearly as easy as it could be.
  6. Better IDE support
    1. RLS is alright, but still has ways to go, and the 2.0 efforts are promising, but we have to see these things through.
    2. Parsing Rust is not easy, the vim syntax highlighter struggles with large Rust files.
  7. Further work on unsafe guidelines.

  1. If you're reading this after 2099, sorry for the inconsistency.

  2. We're hiring! You can reach me at bernardo@standard.ai