September 07, 2023 - 3270 words - 17 mins
This post is coauthored by Tomasz Nowak and Predrag Gruevski. It describes work the two of us did together with Bartosz Smolarczyk, Michał Staniewski, and Mieszko Grodzicki.
cargo-semver-checks is a helpful tool for preventing the semver violations that every so often cause ecosystem-wide pain.
This is why it earned a spot in the CI pipelines of key Rust crates like
tokio, and also why the
cargo team hopes to integrate it into
While anedotal evidence is nice, we wanted to get concrete data across a large sample of real-world Rust code.
May 08, 2023 - 3724 words - 19 mins
A few days ago, I started polls on Mastodon and Twitter whether adding a new private type, or an import, can ever be a major breaking change. The consensus was that this should be impossible.
I agree with that. It should be impossible.
I've discovered a way to cause a previously-public type or function to disappear from a crate's public API by making innocuous-seeming changes like adding a private type or adding an import, etc.
It is not a hypothetical problem, either — I've found at least one real-world Rust project that has been affected by it.
April 05, 2023 - 2166 words - 11 mins
For the longest time, I thought that "sealed trait" in Rust was a singular concept implementable in one specific way. To prevent downstream crates from implementing your traits, you make the traits sealed — done, end of story. I was wrong! It turns out there are multiple ways to seal traits, forming a pleasant spectrum of options:
April 01, 2023 - 2208 words - 12 mins
Happy April 1st! This post is part of April Cools Club: an effort to publish genuine posts on topics our usual audience would find unexpected. The tech content will be back soon!
Over the many years I spent heavily involved in intern and full-time recruiting at
$PREVIOUS_JOB, multiple people have commented something to the effect of: "How come Predrag always gets the best people?"
This post is a series of vignettes showing three of the less-obvious ideas that gave us an edge,
March 06, 2023 - 813 words - 5 mins
We've already explored some of the dark corners of Rust semantic versioning on this blog:
February 07, 2023 - 3926 words - 20 mins
This post describes work in progress: how
cargo-semver-checks will benefit from the upcoming query optimization API in the Trustfall query engine. Read on to learn how a modern linter works under the hood, and how ideas from the world of databases can improve its performance.
January 31, 2023 - 1194 words - 6 mins
I recently embarked on a quest: revamp the cargo-semver-checks import-handling system so that moving and re-exporting an item stops being incorrectly flagged as a major breaking change. This is how crate authors can reorganize or rename items: just re-export the items in the original location under …
January 26, 2023 - 1848 words - 10 mins
I've been saying for a while now that semantic versioning in Rust is tricky and full of unexpected edge cases.
My last post mentioned that some Rust structs can be converted into enums without requiring a major version bump. It introduced a non-exhaustive struct called Chameleon that had no public f…
January 24, 2023 - 1611 words - 9 mins
EDIT: The Rust API evolution RFC distinguishes between breaking changes and changes that require a new semver-major version (called major changes). All major changes are breaking, but not all breaking changes are major. Changing a struct to an enum is always breaking (as pointed out on r/rust) but i…
December 23, 2022 - 1946 words - 10 mins
cargo-semver-checks ends 2022 with 40,000 downloads from crates.io, able to prevent 30 different kinds of semver issues, and having done so in real-world use cases.
Inspired by Yoshua Wuyts' "Rust in 2023 (by Yosh)" post, here are my thoughts on cargo-semver-checks in 2022, and what I look…
November 27, 2022 - 2421 words - 13 mins
Undefined behavior (UB) is a tricky concept in programming languages and compilers.
Over the many years I've been an industry mentor for MIT's 6.172 Performance Engineering course,
An excellent class that I highly recommend. It's very thorough and hands-on, at the expense of also requiring a lot of…
October 03, 2022 - 1121 words - 6 mins
I had a lot of fun spending nights-and-weekends time participating in the HYTRADBOI Jam, a global hack week aimed at building "exciting and weird" data-centric solutions to familiar problems.
The name HYTRADBOI might sound familiar: the jam is associated with the same conference where I gave my "How to Query (Almost) Everything" talk talk in April this year.
I jammed on two projects: one solo and one with a friend. The projects ultimately were very successful and mostly-successful, respectively.
September 19, 2022 - 1887 words - 10 mins
The saying usually goes: "If at first you don't succeed, try, try again."
But in the Safari web browser under the right conditions, trying again after succeeding once can get you in trouble.
This is my recent debugging adventure.
August 25, 2022 - 1866 words - 10 mins
I recently built
cargo-semver-checks, a linter that ensures crates adhere to semantic versioning. This is why and how I built it.
Fearless development is a key theme throughout Rust.
"If it compiles, it works",
fearless concurrency, etc.
But there's one aspect of Rust (and nearly all other languages) that isn't entirely fearless yet:
cargo update, upgrading the versions of the project's dependencies.
May 17, 2022 - 3096 words - 16 mins
A beginner-friendly introduction to compilers: follow along as we build a compiler from scratch, or fork the code on GitHub and add your own optimizations too! In this episode: value numbering helps track how values are used in the program.
Last time on Compiler Adventures, we implemented constant p…
April 01, 2022 - 1732 words - 9 mins
Happy April 1st! A group of folks and I decided to do something different this year: instead of publishing fake things, we’re publishing real posts on very different topics than our readers usually expect from our blogs. The tech content will be back soon! Check out the other April Cools posts here.…
February 17, 2022 - 2392 words - 12 mins
A beginner-friendly introduction to compilers: follow along as we build a compiler from scratch, or fork the code on GitHub and add your own optimizations too! In this episode: propagating constant values to eliminate more instructions.
Last time on Compiler Adventures, we wrote an optimization that…
February 03, 2022 - 1955 words - 10 mins
A beginner-friendly introduction to compilers: follow along as we build a compiler from scratch, or fork the code on GitHub and add your own optimizations too! In this episode: eliminating no-op instructions.
What part of computer science feels most like arcane magic? I'd say compilers. "The ma…
January 26, 2021 - 1115 words - 6 mins
Distributed systems courses frequently introduce
the Paxos and
two-phase commit (2PC) protocols
in quick succession.
On one hand, this is a reasonable educational choice, as Paxos and 2PC are both examples
of consensus algorithms used in the real world.
On the other, it leads many students toward th…