Blog
"We never update unless forced to" — cargo-semver-checks 2024 Year in Review
January 21, 2025 - 2371 words - 12 minscargo-semver-checks
ends 2024 having improved dramatically over the course of the year: 12 new releases featuring 63 new lints, with 1175 merged PRs from 57 authors across the many repos that make the project tick. Let's recap what we learned, the biggest things we shipped, and the facets of the project that made it to the conference and podcast circuits.
Breakage! in the Cargo.toml — How Rust Package Features Work (And Break)
December 04, 2024 - 1822 words - 10 minscargo-semver-checks
v0.37 can now scan Cargo.toml
files for breakage! In this post: a primer on Rust package features, and how innocuous-looking Cargo.toml
changes can break your users.
Is this trait sealed, or not sealed — that is the question
September 03, 2024 - 2163 words - 11 minscargo-semver-checks
v0.35 can determine whether Rust traits are "sealed", allowing it to catch many tricky new instances of SemVer breakage. Why is accurate sealed trait detection so important, and why is implementing it correctly so hard?
How to Query (Almost) Everything
July 22, 2024 - 6387 words - 32 minsIn 2022, I gave a talk at a virtual conference with an unforgettable name: HYTRADBOI, which stands for "Have You Tried Rubbing a Database On It?" Its goal was to discuss unconventional uses of database-like technology, and featured many excellent talks.
My talk "How to Query (Almost) Everything" received copious praise. It describes the Trustfall query engine's architecture, and includes real-world examples of how my (now-former) employer relies on it to statically catch and prevent cross-domain bugs across a monorepo with hundreds of services and shared libraries. For example:
read moreThe Wi-Fi only works when it's raining
April 01, 2024 - 2033 words - 11 minsSemVer in Rust: Tooling, Breakage, and Edge Cases — FOSDEM 2024
March 18, 2024 - 10726 words - 54 minsLast month, I gave a talk titled "SemVer in Rust: Breakage, Tooling, and Edge Cases" at the FOSDEM 2024 conference.
The talk is a practical look at what semantic versioning (SemVer) buys us, why SemVer goes wrong in practice, and how the cargo-semver-checks
linter can help prevent the damage caused by SemVer breakage.
TL;DR: SemVer is impossibly hard for humans, but automated tools can cover our greatest weaknesses.…
read moreFour challenges cargo-semver-checks has yet to tackle
January 23, 2024 - 2117 words - 11 minsMy last post covered the key cargo-semver-checks
achievements from 2023. Here are the biggest challenges that lie ahead!
Many of the remaining challenges in cargo-semver-checks are obvious: we all want more lints, fewer false-positives, etc. etc. Let's set those aside.
Instead, let's talk about four non-obvious challenges we have yet to tackle:
read moreHighlights of 2023 for cargo-semver-checks
January 16, 2024 - 1679 words - 9 minsChecking semver in the presence of doc(hidden) items
November 18, 2023 - 2729 words - 14 minscargo-semver-checks
v0.25 squashes nearly all bugs related to doc(hidden)
items — its most common source of false-positives. What does doc(hidden)
mean in Rust, and why was handling it correctly so hard?
Semver violations are common, better tooling is the answer
September 07, 2023 - 3208 words - 17 minsThis 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.
Anecdotally, 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 cargo
itself.
While anedotal evidence is nice, we wanted to get concrete data across a large sample of real-world Rust code.…
read moreBreaking semver in Rust by adding a private type, or by adding an import
May 08, 2023 - 3261 words - 17 minsA 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.
read moreA definitive guide to sealed traits in Rust
April 05, 2023 - 1836 words - 10 minsFor 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:
read moreMediocrity can be a sign of excellence, and other stories
April 01, 2023 - 2208 words - 12 minsHappy 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,…
read moreRe-exporting an enum with a type alias is breaking, but not major
March 06, 2023 - 678 words - 4 minsWe've already explored some of the dark corners of Rust semantic versioning on this blog:
read moreSpeeding up Rust semver-checking by over 2000x
February 07, 2023 - 3696 words - 19 minsThis 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.
Moving and re-exporting a Rust type can be a major breaking change
January 31, 2023 - 995 words - 5 minsSome Rust breaking changes don't require a major version
January 26, 2023 - 1736 words - 9 minsTurning a Rust struct into an enum is not always a major breaking change
January 24, 2023 - 1526 words - 8 minscargo-semver-checks today and in 2023
December 23, 2022 - 1946 words - 10 minsFalsehoods programmers believe about undefined behavior
November 27, 2022 - 2421 words - 13 minsMy HYTRADBOI'22 Jam
October 03, 2022 - 1121 words - 6 minsI 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.…
read moreDebugging Safari: If at first you succeed, don't try again
September 19, 2022 - 1847 words - 10 minsThe 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.…
read moreToward fearless cargo update
August 25, 2022 - 1835 words - 10 minsI 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.