profile picture

9 pages tagged with "rust"

Breaking semver in Rust by adding a private type, or by adding an import

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.

read more

A definitive guide to sealed traits in Rust

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:

read more

Re-exporting an enum with a type alias is breaking, but not major

March 06, 2023 - 813 words - 5 mins

We've already explored some of the dark corners of Rust semantic versioning on this blog:

read more

Speeding up Rust semver-checking by over 2000x

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.

read more

Moving and re-exporting a Rust type can be a major breaking change

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 … read more

Some Rust breaking changes don't require a major version

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… read more

Turning a Rust struct into an enum is not always a major breaking change

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… read more

cargo-semver-checks today and in 2023

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… read more

Toward fearless cargo update

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.

read more