Sign in

Predrag Gruevski

@predr.ag
1.9K followers 387 following 662 posts

Querying (Almost) Everything // Frontier Systems @ OpenAI // Author of cargo-semver-checks & Trustfall // predr.ag/blog // ex Kensho // MIT alum // hachyderm.io/@predrag // not from around here 🇲🇰 // he-him

PostsRepliesMedia
Predrag Gruevski @predr.ag · 21/09/2026
GitHub Actions + Rust's Miri can leak your secrets in CI 🧵 If you run Miri in CI: - upgrade to the 2026-09-22 nightly - clear caches - rotate any secrets that the `cargo miri` CI job had access to GPT-6 Astra helped find this 🦀
GitHub Actions makes it possible to cache directories between runs. Typical setups allow CI runs on main (and other branches) to write to cache, and PRs can only read from cache (preventing cache poisoning). Rust projects tend to speed up CI by caching binaries built by cargo install and sometimes the contents of target/.

PR CI can be triggered by anyone who can open PRs on your repository. GitHub requires maintainer approval for the first PR, but future PRs will rerun CI on every push. Anyone who has previously landed a change can trigger a CI run extracting information from cached target/ and then cover their tracks by pushing a second commit to the PR.

GitHub sometimes hides overwritten commits in its UI, making this kind of attack harder to detect. CI run logs and overwritten commits are also deleted after a few months.

When cargo miri is invoked, Miri needs to retain build-relevant environment variables between runs. The current code to do so achieves this by storing all environment variables to target/. This, of course, persists when target/ is cached.

If your environment contained secrets, these can now be accessed by PRs via the cache.
1389
Predrag Gruevski @predr.ag · 01/09/2026
New programming book arrived in the mail 👀 There's never been a better time to think deeply about the structure behind the code we cause to exist.
Logic for Programmers, a book by Hillel Wayne
1446
Predrag Gruevski @predr.ag · 01/08/2026
With any luck, this is the cargo-semver-checks release that will start scanning the Rust standard library for breakage. Enjoy v0.50.0! What a fitting moment for a nice round number 🎉 Expect a blog post soon!
cargo-semver-checks v0.50.0 release notes.

- Support for rustdoc JSON v61 for the latest nightly Rust
- One new lint: `auto_trait_impl_added`
- Bugfix in `constructible_struct_adds_field` to properly account for existing `pub` but `#[doc(hidden)]` fields.
- Support for parsing rustdocflags from `.cargo/config.toml` and some minor bugfixes
- Thanks to @taiki-e for accepting our upstream patches and promptly releasing them in `cargo-config2` so we can use them!
0453
Predrag Gruevski @predr.ag · 27/07/2026
"If your rules aren't checkable with a tool, they are just entertainment. They aren't being followed." - Gerard Holzmann #systemsdistributed
Slide saying "rules are most useful if they are sparse, clear, demonstrably correlate with risk, and are checkable with code."
0123
Predrag Gruevski @predr.ag · 03/07/2026
Day 5, a picture worth a thousand words 👇 I put an API-breaking `#[doc(hidden)]` in my local build of the Rust standard library, and asked cargo-semver-checks to find it. See for yourself!
cargo-semver-checks output where the "function now doc hidden" lint is triggered, warning that the "black_box" function in library/core/src/hint.rs is now #[doc(hidden)] and no longer public API. The run took 6.7s total.
251
Predrag Gruevski @predr.ag · 24/05/2026
Sad that RustWeek is over, and glad I got to spend the week with so many wonderful people. Next time you are delighted by how a Rust feature works, say thanks to all these folks who spent the week hashing out every possible edge case! Can't wait for next year's RustWeek! #rustweek #rustweek2026
All the Rust Project devs posing for a photo at the end of the All Hands. A huge group of people!
0415
Predrag Gruevski @predr.ag · 19/05/2026
Hello from Rust Week 2026! The venue is a movie theater, so the organizers made a batch of movie posters customized to the event. Here's just one of them ✨ #rustweek2026 #rustweek #rustlang
Movie poster in the style of the poster for Project Hail Mary, but titled Project Hail Miri with Ferris looming above a striking green planet.
2937
Predrag Gruevski @predr.ag · 11/01/2026
Shout-outs to the kind folks who make this work possible by funding cargo-semver-checks 🙏
All this was made possible through the funding provided by the Rust Foundation Fellowship Program, Amazon, Rerun, Accelerant, Astral, Zoo, the generous individuals who support my work via GitHub Sponsors, as well as the Google Summer of Code program where I was a mentor. To everyone who makes what I do possible, thank you 🙏
030
Predrag Gruevski @predr.ag · 11/01/2026
I also propose a change in how we measure success going forward. I hate gameable metrics. Let's build what's most valuable for the community, not what's easiest to quantify and brag about.
"Total number of lints" is a fun number to look at, but increasingly just a vanity metric. I believe the community will be best served by us tackling some of our long-standing (and most difficult) challenges, instead of trying to chase exponential lint growth by itself. The challenges include:
- making ecosystem-level SemVer studies 50x cheaper by the end of 2027, and completing such a run
- completing type-checking lints and cross-crate linting capabilities
- officially starting the process of merging `cargo-semver-checks` into cargo

Full info here: https://predr.ag/blog/cargo-semver-checks-2025-year-in-review/#the-path-forward-for-2026-and-beyond
100
Predrag Gruevski @predr.ag · 11/01/2026
Here's everything you'll find in the post above! If you're a regular reader, some of these sections may be familiar. There are links so you can skip ahead!
Table of contents for the blog post

- Goal: Fearless `cargo update`
- What we shipped in 2025
  - 122 new lints is *a lot*
  - Discovering a soundness bug in Rust
  - Doubling the lints without doubling the runtime
  - Why compiling the same Rust program might succeed or fail depending on the current directory
  - Resolving the edge cases of `#[do
- Conference talks and podcast appearances
  - What it'll take to eradicate unintended breakage from Rust — RustWeek
  - The Past, Present, and Future of SemVer in Rust — RustForge
  - Cursed Rust — A Surprise Talk at RustForge
  - A Universal Query Engine in Rust — Developer Voices
  - `cargo-semver-checks` — Open Source Security
- The path forward for 2026 and beyond
  - We've already started down this path
  - What success will require, and how you can help
100
Predrag Gruevski @predr.ag · 30/12/2025
SemVer is tricky in all languages. But in #rustlang it's easier than ever before! By the end of 2024, cargo-semver-checks' capabilities were growing exponentially: 30 -> 57 -> 120 lints. We now end 2025 with 242 lints — 122 new lints were merged this calendar year 🎉 The exponential continues!
Screenshot from the cargo-semver-checks 2024 year in review post featuring a diagram of the number of lints at the end of each calendar year. 2022 ended with 30 lints, 2023 ended with 57, 2024 ended with 120 lints.

Link to the post: https://predr.ag/blog/cargo-semver-checks-2024-year-in-review/
0265
Predrag Gruevski @predr.ag · 30/11/2025
On behalf of the cargo-semver-checks project, it's my pleasure to recognize @jyn.dev's irreplaceable and tireless work in the #rustlang community 🦀 I'll share just one anecdote; you can click on the GitHub Sponsors link at the end of the thread to see more 🧵
GitHub Sponsors email stating: "You sponsored @jyn514! Sponsorship amount: $1000 one time"
36613
Predrag Gruevski @predr.ag · 29/11/2025
Here's the code in question. Strange, right?
fn breaks() -> impl Debug + ?Sized {
    123
}

// error[E0277]: the size for values of type `impl Debug + ?Sized` cannot be known at compilation time
//  --> src/lib.rs:3:16
//   |
// 3 | fn breaks() -> impl Debug + ?Sized {
//   |                ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
//   |
//   = help: the trait `Sized` is not implemented for `impl Debug + ?Sized`
//   = note: the return type of a function must have a statically known size

async fn works() -> impl Debug + ?Sized {
    123
}
// no error!
261
Predrag Gruevski @predr.ag · 24/09/2025
I have a paper for you to read: people.csail.mit.edu/nickolai/pap...
Four plots showing a sudden performance collapse as more cores are added. Different workloads collapse at different points: some around 2 cores, others at 10 or 36. But in all cases, running the workload at the full 48 cores is much slower than taking some cores away.
041
Predrag Gruevski @predr.ag · 21/09/2025
Here's the animation (but do check out the release notes too!)
090
Predrag Gruevski @predr.ag · 21/09/2025
cargo-semver-checks v0.44.0 is live — we've hit 200 lints ✨ Don't miss this *adorable* animation in the release notes, courtesy of the amazingly talented @dekirisu.com Check it out here: github.com/obi1kenobi/c... #rust #rustlang #semver
Screenshot of the cargo-semver-check v0.44.0 release page.

It touts 22 new lints, for a total of 200 lints! In celebration, it includes an adorable animation of Ferris standing alongside a conveyor belt which transports crates off an assembly line. Each crate passes through a cargo-semver-checks scanning station, which applies a "PASS" or "FAIL" sticker to it. It seems like a crate has just failed SemVer checking! Ferris picks it off the conveyor belt, and throws it into a hopper labeled "Revise". This is how all crates being shipped uphold SemVer! All is well.
2191
Predrag Gruevski @predr.ag · 05/09/2025
Sometimes when I work on #rustlang cargo-semver-checks, I feel I need "Look What You Made Me Do" playing in the background. Here's a legal type and function signature I wrote today to test some upcoming lints 👇
impl<S: Clone> Example<'static, S> {
    pub fn hello<'a, T, const N: usize>() -> impl for<'n> Fn(&'n i64) -> &'n i64 + use<'a, T, S, N> {
        |x| x
    }
}
2120
Predrag Gruevski @predr.ag · 28/08/2025
70% of security vulnerabilities are memory safety related, across a variety of studies in mature, well-maintained codebases. Looking specifically at critical security vulnerabilities, the number goes up to 94%. From @david-sankel.bsky.social's talk at @rustforgeconf.com
70% of memory safety vulnerabilities have a root cause related to memory safety, across studies done by Microsoft, Google Android, Google Chromium, Mozilla, and a general survey of zero-day vulnerabilities.

Mozilla's survey of critical security vulnerabilities shows 94% of them were memory safety related.
180
Predrag Gruevski @predr.ag · 10/08/2025
Who else is going to be at Rust Forge btw? Look at this stacked list of speakers and topics. I'm really looking forward to meeting all these folks in person! rustforgeconf.com
Speakers

James Blackwood-Sewell
PGRX - How Rust reshaped the Postgres ecosystem

Adam Chalmers
Why Rust for startups

Meghan Clark
Mixed Reality Network Introspection

Stephan Dilly
Build a Game with Bevy

EncodePanda
Rust for the Rest of Us: Your Survival Guide

Predrag Gruevski
The Past, Present, and Future of SemVer in Rust

Adam Harvey
Crate security in 2025

Azriel Hoh
The Development Experience Is Different With Rust

Paul Hummer
Other People's Code : Domain Specific wasm

Elias Junior
Tackling complexity a test at a time

Steve Klabnik
Rust is (much) more than safety

Andrey Konstantinov
Reflect Your Rust API into the World

Jonas Kruckenberg
Panic! At The Disk Oh!

David Lattimore
Wild build times

Laura Bell Main
AppSec for developers with deadlines

Orhun Parmaksız
Becoming a terminal chef with Ratatui, Rust rocks (literally)

Jack Purvis
From Ruby to Rust: building a live visual performance tool with Rust

Anders Rasmussen
Make your own own smart watch

David Sankel
Engineering the Future at Adobe: Why Rust is Key to Our Next Chapter

Tom Simpson
Designing superconducting magnets for fusion power

Jeremy Wells
Take your web app offline with Rust and Tauri

Mikey Williams
Rust in color: embedded LED art

Ben Wishovich
🦀 cargo new blog: Shipping a Site with Leptos

Ross Younger
Land of the long fat pipe: the quest for faster file transfers

Mix Irving
Peer-2-Peer Data Visualisation
010
Predrag Gruevski @predr.ag · 10/08/2025
✨ cargo-semver-checks v0.43.0 is out ✨ This release cycle focused on making it a joy to use and build. We improved performance on large crates, cut down our CI time, tackled a large rustdoc JSON format migration, and paid down technical debt. Enjoy!
v0.43.0 - In this release
- Spotlight: I'm giving a talk at Rust Forge!
- Performance improvements
- 1 new lint, for a total of 178

This release requires Rust 1.87+ both to install (MSRV) and at runtime. Future releases will require Rust 1.88+.

Spotlight: I'm giving a talk at Rust Forge!

Rust Forge is a creative new conference organized by Rust in Action author Tim McNamara. It's scheduled for 27-30 August 2025 in Wellington, New Zealand.

My talk is titled "The Past, Present, and Future of SemVer in Rust" and I'm extremely excited about it! Here's a short description:

At least 1-2 times per week, accidental breaking changes sneak into the new release of some popular Rust package, despite the maintainers' best efforts. Why is this still a problem 10 years after Rust 1.0? What will it take to finally stop such breakage, so we can have fearless cargo update?

It's not too late to grab a ticket! I hope to see you there!Performance improvements

Supporting an exponentially-growing number of lints requires periodic maintenance in the form of mandatory performance engineering, Without it, things would quickly get out of hand, and large crates and large workspaces would be affected first. To prevent that, this release cycle focused on both internal and external improvements.

Externally-visible improvements include lint execution time improvements, courtesy of a new query profiling tool prototype developed by @CLIDragon. This allowed us to add targeted new indexes that speed up the execution of some lints by as much as 10x! After these optimizations, running the full suite of lints on Rust's largest crates needs only ~2s, down from around ~8s previously.

Internal improvements include a variety of optimizations aimed at reducing the time taken by our CI suite, from an original of ~7min for cargo test down to around ~1min.

If you're wondering why cargo test used to take 7min in the first place: our test suite runs ~250000 lint queries to ensure correctness and keep false-positives out! Even extremely cheap operations done 250k times add up very quickly! After the optimizations, we still run those 250k queries — we didn't sacrifice correctness at all, but merely cut out avoidable overhead.

New lints

We added only one new lint in this release, tracking an additive-only API change: enum_must_use_removed. This lint group remains opt-in-only.
190
Predrag Gruevski @predr.ag · 07/06/2025
Experienced #rustlang engineers never break SemVer. Nobody needs cargo-semver-checks — just be more careful </s> I even *had left myself a note* that the next release needs to be a major bump. Too bad I only saw the note after cargo-semver-checks stopped the publish job!
GitHub publishing pipeline in a failed state. The commit title is "Release v0.23.2 with support for rustdoc JSON v46." The pipeline has stopped immediately prior to the "Publish to crates.io" stage, having failed the job titled "Check for semver compliance."Logs of the failed semver-checking job. Four breaking changes are listed, showing the effects of removing support for rustdoc JSON format v36: three enum variants have been deleted, and the `v36` feature has been removed from the crate's Cargo.toml features list.
1191
Predrag Gruevski @predr.ag · 14/05/2025
Update on the Rust Vision Doc, by @nikomatsakis.com, @timclicks.dev, and Jack Huey Day 2 of #RustWeek closing strong!
Niko, Jack, and Tim giving their talk. The slide reads:

Conclusions: 
- Rust Vision Doc aims to give us insight into the state of Rust
- We are happy to have help: come be an interviewer, or talk to Niko or Jack
060
Predrag Gruevski @predr.ag · 13/05/2025
Excited for day 1 of #RustWeek! So many good talks coming up 🤩 If you like cargo-semver-checks (and especially if you fund it on GitHub Sponsors!), find me in the hallway — I have something for you 👀
0203
Predrag Gruevski @predr.ag · 22/04/2025
New cargo-semver-checks just dropped, enjoy! And if you're enjoying, please support the project on GitHub Sponsors 😍 github.com/obi1kenobi/c...
v0.41.0 release of cargo-semver-checks

# In this release
- 16 new lints, for a total of 164
- Spotlight: Google Summer of Code
- Bugfix: false-positive sealed trait lints

This release requires Rust 1.84+ both to install (MSRV) and at runtime. Future releases will require Rust 1.85+.

# Spotlight: Google Summer of Code

`cargo-semver-checks` is participating in Google Summer of Code, a program aimed at bringing new contributors into open source software development.

This is our second year participating in the program under the Rust umbrella. Last summer, @suaviloquence joined us to design and build the ability for users to configure which lints run on their projects, on which SemVer changes, and with what effect such as raising an error vs warning. This is a foundational capability for our project! For example, it allows users to temporarily disable a lint that exhibits buggy behavior in their project, such as a false-positive.

The application process for this year's Google Summer of Code concluded two weeks ago, and we're currently in the evaluation process. The selected projects will be announced in early May. We thank everyone who applied for their hard work on their proposals, and wish everyone the best of luck!# New lints

We added new 16 lints across several categories. Some of the new lints are error-by-default, while others are warnings meant to flag changes deserving closer review, or even opt-in only and disabled by default while we do more work to improve their user experience.

API breakage:
- `enum_struct_variant_changed_kind`
- `enum_non_exhaustive_tuple_variant_changed_kind`

Item deprecations, which cause lints in downstream use:
- `enum_struct_variant_field_marked_deprecated`
- `enum_tuple_variant_field_marked_deprecated`
- `enum_variant_marked_deprecated`

Compatibility risks, such as changes that may require a SemVer major bump to revert, or may otherwise represent unintended API changes without being SemVer-major themselves:
- `enum_no_longer_non_exhaustive`
- `enum_variant_no_longer_non_exhaustive`
- `enum_repr_int_added`
- `function_no_longer_unsafe`
- `function_now_const`

Additive-only API changes (opt-in only; more work required):
- `enum_non_exhaustive_struct_variant_field_added`
- `enum_non_exhaustive_tuple_variant_field_added`
- `non_exhaustive_enum_added`
- `pub_const_added`
- `pub_static_added`
- `union_added`

Thanks to @shreyans413, @GlitchlessCode, @Frank-III, @qstommyshu, and @sandptel for contributing to this release!Bugfix: false-positive sealed trait lints

In rare circumstances, `cargo-semver-checks` had the tendency to mis-classify traits as sealed even though that wasn't actually the case. This manifested as false-positive lints stating that traits have newly become sealed (a breaking change) or that a previously-sealed trait is no longer sealed (a future-compatibility warning).

After quite a bit of work, we were able to diagnose the issue as a logic error in the cycle-tracking code of our sealed trait analysis. #1200 has more information.

This portion of `cargo-semver-checks` has 2000+ lines of test code _specifically_ dedicated to covering its edge cases. This bug made it through all of that without getting caught — that's how complex this space is.

We're grateful to the folks who contributed high-quality bug reproductions to help us diagnose the problem in #1200. We're also grateful to the generosity of our GitHub Sponsors who make it possible for `cargo-semver-checks` to continue powering through this very complex space.
2214
Predrag Gruevski @predr.ag · 04/04/2025
I think I found something weird & scary with `#[target_feature]` in #rustlang. Is this expected? This feels like it should *at minimum* trigger a lint. How am I supposed to know whether trait impls added extra safety preconditions — especially when using `dyn/impl Trait` and/or an unsealed trait?
pub trait Example {
    unsafe fn demo(&self) {}
}

pub struct S;

impl Example for S {
    // This isn't applied to the trait's fn!
    #[target_feature(enable = "avx2,aes")]
    unsafe fn demo(&self) {}
}

pub fn accept_dyn(value: &dyn Example) {
    // SAFETY: umm ???
    // Who knows what #[target_feature]
    // attributes the trait impl has imposed?!
    unsafe { value.demo() }
}
271
Predrag Gruevski @predr.ag · 08/03/2025
✨ cargo-semver-checks v0.40 is out ✨ github.com/obi1kenobi/c...
## In this release
- 21 new lints, for a total of 148!
- Spotlight: `#[doc(hidden)]` and sealed lints

This release requires Rust 1.83+ both to install (MSRV) and at runtime. Future releases will require Rust 1.84+.

## Spotlight: `#[doc(hidden)]` and sealed lints

When is "this trait can be implemented" part of the trait's public API?

At a high level, the answer is: when writing an `impl` of that trait for our own type doesn't require using any `#[doc(hidden)]` items. But you've been following `cargo-semver-checks` long enough to know the *full answer* is much more complex. And getting the right answer here affects the correctness of a ton of lints!

Good news! This `cargo-semver-checks` release ships with a much more sophisticated system for analyzing whether traits can be implemented or are instead "sealed." The new system is more thorough, more nuanced, and faster to boot!

Read more about it here: https://predr.ag/blog/when-is-trait-can-be-implemented-public-api/
1141
Predrag Gruevski @predr.ag · 26/02/2025
Hey, look at that! Number go up, and it's a round number again!
Screenshot of a Bluesky's "followers" list showing I have exactly 1500 followers now.
1150
Predrag Gruevski @predr.ag · 31/01/2025
"When can a trait be implemented without touching `#[doc(hidden)]` items?" Simple question, extremely complex answer! Most intense 2000 lines I've written in a long time! Still needs cleanup & refactoring, but it's passing tests! github.com/obi1kenobi/t...
An example of a "public API sealed" trait is:

pub trait Example {
    #[doc(hidden)]
    type X;
}

Any impl of Example outside of its crate must name the Example::X item, and in doing so refer to non-public-API. Therefore, such an impl is outside the public API of Example, and may suffer breakage outside of major version bumps of Example's crate.

Crates can be public-API-sealed in many ways, including:
- #[doc(hidden)] (without #[deprecated]) on associated types without a default
- #[doc(hidden)] (without #[deprecated]) on associated constants without a default value
- #[doc(hidden)] (without #[deprecated]) on associated functions / methods without a default implementation
- associated functions / methods taking an "importable but not public API" parameter
- associated functions / methods returning an "importable but not public API" type

"Importable but not public API" means:
- The item has at least one path by which it can be imported from an external crate. That path passes through at least one item that is simultaneously #[doc(hidden)] and not #[deprecated], such as the imported item itself, a module, or a re-export).
- The item has no paths by which it can be imported such that no item along that path is #[doc(hidden)] and not #[deprecated].
1103
Predrag Gruevski @predr.ag · 28/01/2025
Happy "new cargo-semver-checks release" day! ✨ 20 new lints ✨
## In this release
- 20 new lints, for a total of 127!
- Spotlight: Merging into `cargo`

This release requires Rust 1.81+ both to install (MSRV) and at runtime. Future releases will require Rust 1.83+.

## Spotlight: Merging into `cargo`

While `cargo-semver-checks` is currently a standalone tool, Rust's `cargo` team plans to eventually make it a built-in part of `cargo` itself. Here's how that would work.

When users run `cargo publish` today, `cargo` first runs a series of checks to make sure everything is in order. For example, it ensures that the code repository doesn't include any uncommitted changes, so as not to accidentally publish uncommitted code to crates.io:
```
$ cargo publish
    Updating crates.io index
error: 1 files in the working directory contain changes that were not yet committed into git:

src/lib.rs

to proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag
```

`cargo-semver-checks` is planned to become another such pre-publish check, equivalent to running `cargo semver-checks && cargo publish` today. Of course, there are situations where maintainers may prefer to *intentionally* publish breaking changes in a non-major version, such as for a sufficiently critical security fix. The automatic semver-check will be overridable by passing a flag analogous to the `--allow-dirty` flag for uncommitted changes.

While we're excited to merge `cargo-semver-checks` into `cargo`, we are proceeding with caution before enabling it by default. We want to ensure "merge day" is a day of celebration for the entire Rust community, instead of causing frustration and further breakage! Good news: you can help us do that! Consider:
- Reporting any issues you find, including any suspected false-positives with our lints.
- Contributing lints to make `cargo-semver-checks` smarter
- Funding the project via GitHub Sponsors
191
Predrag Gruevski @predr.ag · 09/01/2025
I like to play "Where's Waldo" as much as the next person, but not during code review. Let's have more tools that point out things humans might miss!
A "Where's Waldo" book cover featuring a large crowd of cartoonish people, with Waldo among them in his red and white striped shirt. He's really hard to notice in the crowd, so he's circled to make him easier to find, solving the puzzle.
000
Predrag Gruevski @predr.ag · 09/01/2025
cargo-semver-checks found the problem in this change, saving the project from breaking SemVer. Manifest linting for the win! 🔥 Do you see the breaking change? #rust #rustlang #semver
A change being applied to a Rust Cargo.toml file. An optional dependency called `mock_instant` ("mock underscore instant") is being removed, and a feature called `mock-instant` ("mock dash instant") is changed to no longer enable the `mock_instant` ("mock underscore instant") feature.

The problem is a lot more obvious when I make the spelling explicit, isn't it? :)
170
Predrag Gruevski @predr.ag · 11/12/2024
cargo-semver-checks v0.38 is live, enjoy 🦀🔥 @orhun.dev and I live-streamed writing one of these new lints last weekend, if you want to see how the proverbial #rustlang sausage gets made!
Release notes screenshot:

In this release:
- 12 new lints, for a total of 106!
- Bugfix for packages using the "SemVer trick"
- Spotlight: Performance via parallelism

Spotlight: Performance via parallelism

cargo-semver-checks is on a trajectory of doubling its number of lints every year. But more lints mean more code scanning work to be done! And nobody likes slow tools, so we had to parallelize!

We began taking a serious look at performance in early 2023. Compared to that point ~almost two years ago:
- Lint checking time has reduced by 20%, in wall-clock terms & measured on the exact same hardware.
- Yet, we run over 2.5x as many lints in that time!

We've aimed to parallelize as much of the execution of the tool as possible, with help from the rayon library. Today, both the lint execution and the rustdoc indexing steps use rayon to distribute the work across all available cores on your system.

[It continues...]
1102
Predrag Gruevski @predr.ag · 10/12/2024
Huge thanks to @rerun.io and @ernerfeldt.bsky.social for sponsoring my work on cargo-semver-checks 🙏 To celebrate, I'll write 5 new lints today ✨
Rerun.io logo: a 3D-stylized letter "R" in white on a black background.
0252
Predrag Gruevski @predr.ag · 05/12/2024
In #rustlang, Cargo.toml changes that seem innocuous can break your users! As of today, cargo-semver-checks has you covered 😇 Here's how 👇 predr.ag/blog/breakag...
Breakage in the Cargo.toml — how Rust package features work (and break)

cargo-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 changes can break your users.
1226
Predrag Gruevski @predr.ag · 27/11/2024
Gotta love it when you're writing two different programs at the same time, and they have to rhyme. do_stuff() is 10 lines long in the actual code, and this structure repeats half a dozen times in the same function.
Rust code that relies on conditional compilation to enable or disable "rayon" parallelization. The structure is:
- conditionally include a rayon line
- otherwise, include a non-rayon line
- then do some stuff they have in common
- then again conditionally include a rayon line
- or include the non-rayon line otherwise
- then more stuff in common.
140
Predrag Gruevski @predr.ag · 20/11/2024
Only if there are no accidental breaking changes in any of the upgraded versions! As the talk shows, accidental breakage is quite common and happens ~all the time even to expert maintainers.
Slide headline: Across the top 1000 crates, 1 to 2 broken new releases happen per week.

Below: This is data from running cargo-semver-checks, and is joint work with Tomasz Nowak, Mieszko Grodzicki, Bartosz Smolarczyk, Michał Staniewski

More info:
https://predr.ag/blog/semver-violations-are-common-better-tooling-is-the-answer/
100
Predrag Gruevski @predr.ag · 19/11/2024
That's certainly a new way to spell my name. Innovation strikes again!
A magazine addressed to "Mr. and Mrs. Drag Gruevski". My name is Predrag, not Drag!
110
Predrag Gruevski @predr.ag · 07/11/2024
Congrats to all #rustlang Google Summer of Code students on completing their projects! Max knocked his cargo-semver-checks project out of the park 🚀 blog.rust-lang.org/2024/11/07/g...
Predrag, who is the author of cargo-semver-checks and who mentored Max on this project, was very happy with his contributions that even went beyond his original project scope:

He designed and built one of our most-requested features, and produced design prototypes of several more features our users would love. He also observed that writing quality CLI and functional tests was hard, so he overhauled our test system to make better tests easier to make. Future work on cargo-semver-checks will be much easier thanks to the work Max put in this summer.

Great work, Max!
070
Predrag Gruevski @predr.ag · 19/10/2024
Enjoy the new cargo-semver-checks release ✨ Preventing more breakage, across more #rustlang versions, in less time than ever before. Check out the full release notes here: github.com/obi1kenobi/c...
cargo-semver-checks v0.36.0

What's changed
We're debuting a new "Spotlight" section in the release notes! We'll use it to shine a spotlight at aspects of cargo-semver-checks that don't usually get flashy headlines, even though they play a critical role.

In this release:
- Spotlight: Supporting many Rust versions at once
- 5 new lints (94 total, who will add lint number 100?)
- Performance upgrades
- Support for comma-separated feature lists

This release requires Rust 1.77+ both to install (MSRV) and at runtime. Future releases will require Rust 1.80+.
050
Predrag Gruevski @predr.ag · 16/10/2024
It's official: I'm a #rustlang Foundation Fellow working on cargo-semver-checks 🎉🦀 Accidental breaking changes suck. Let's eliminate as many of them as we can. foundation.rust-lang.org/news/announc...
SemVer accidents are expensive:
- Maintainers are scrambling to triage, yank, patch, re-publish.
- Users are frustrated: "Why fix something I didn't break?!"
- Community-level harm: "Don't update unless you have to"

Everyone is worse off, at a huge cost to everyone!
4235
Predrag Gruevski @predr.ag · 06/10/2024
Sneak peek of my EuroRust talk, hope to see you there 👀 Jon Gjengset is a hard act to follow so I'm polishing everything until it shines ✨
Build bigger in less time: code testing beyond the basics.

Three techniques:
- invariant testing, represented by engineer Ferris
- snapshot testing, represented by defender Ferris
- deterministic simulation, represented by magician Ferris
120
Predrag Gruevski @predr.ag · 04/10/2024
Had a blast at RustConf 🦀🎉 Let's put an end to accidental SemVer breakage! The talk videos should be up soon. Here are my slides: docs.google.com/presentation...
Predrag in the middle of his talk, standing in front of a giant "RustConf 2024, Montreal" banner.A packed room at Predrag's talk. The cargo-semver-checks logo is visible on the current slide.The talk's title slide: Putting an End to Accidental SemVer-Breaking Changes
030
Predrag Gruevski @predr.ag · 17/09/2024
I was user #59,666 here — what an appropriately cursed number given the kind of programming shenanigans I pull...
120
Predrag Gruevski @predr.ag · 09/09/2024
Excited to meet everyone at #rustconf24 🦀 Check out the free livestream if you couldn't make it in person! Let's put an end to accidental SemVer breakage!
I'm speaking at RustConf 2024, 10-13 September in Montreal.

Don't miss my talk: "Putting an End to Accidental SemVer-Breaking Changes"

Grab your spot today by registering at rustconf.com
020
Predrag Gruevski @predr.ag · 03/09/2024
cargo-semver-checks v0.35 is our biggest release yet 🤩
In this release:
- 10 new lints
- performance upgrades
- improved bug reporting UX & test infra

This release requires Rust 1.77+ both to install (MSRV) and at runtime.

New lints:

We can now detect whether a trait is sealed or not, unlocking many new lints! "Is this lint sealed" is a tricky question full of edge cases — check out our deep-dive into this feature to learn more: https://predr.ag/blog/is-this-trait-sealed-or-not-sealed/

- trait_newly_sealed
- trait_method_added
- trait_method_default_impl_removed
- trait_associated_type_added
- trait_associated_const_added
- trait_associated_type_default_removed
- trait_associated_const_default_removed
- enum_unit_variant_changed_kind
- enum_tuple_variant_changed_kind

Additionally, we enabled the trait_no_longer_object_safe lint. It was previously implemented but was disabled while awaiting updated Rust functionality.
000
Predrag Gruevski @predr.ag · 15/08/2024
SemVer linting across a large range of Rust versions is an underappreciated challenge 🦀 cargo-semver-checks supports Rust 1.77+, meaning it has to support 6 different rustdoc JSON formats at once!
The cargo-semver-checks package's Cargo.toml file.

The dependencies section states that rustdoc JSON format versions 27, 28, 29, 30, 32, and 33 are all supported.
111
Predrag Gruevski @predr.ag · 14/08/2024
✨ cargo-semver-checks v0.34 ✨ New lints + freshly rebuilt with Rust 1.80.1 to ensure we aren't affected by miscompilations or inference breakage. If you like this, please sponsor my work: github.com/sponsors/obi...
cargo-semver-checks v0.34.0

In this release: 
- 3 new lints
- support for rustdoc format v33

This release requires Rust 1.77+ both to install (MSRV) and at runtime. It also ensures cargo-semver-checks continues to build correctly on Rust 1.80, addressing both the inference-breaking change and the floating-point miscompilation issues in 1.80.0.

New lints:
- inherent_method_now_doc_hidden by @orblivion in #821
- union_pub_field_now_doc_hidden by @PedroTurik in #844
- union_must_use_added by @PedroTurik in #845
000
Predrag Gruevski @predr.ag · 31/07/2024
My turn to ship an unexpected breaking change 😅 No amount of expertise can shield us from this. Only better tools can change the status quo.
GitHub conversation. A user reports: "I think it is after this PR not possible to do `cargo install cargo-semver-checks --no-default-features` — it fails to compile. Is that expected? I can't find anything about this in release notes"

I reply:

Oops! 😅

In retrospect, yes, that's a breaking change. I should have called it out in the release notes!

I didn't realize it was breaking and @ggwpez might not have noticed it either.

The irony of a breaking change linter having an unexpected breaking change is not lost on me 😅 This is why I want cargo-semver-checks lints that can check manifests: https://rust-lang.github.io/rust-project-goals/2024h2/cargo-semver-checks.html
020
Predrag Gruevski @predr.ag · 29/07/2024
"When you're working with superconductors, copper is an insulator" #rustlang tools like cargo-semver-checks, release-plz, PyO3, and maturin are helping make fusion power a reality 🦀
Conference talk slide describing the project structure of a Rust + Python library for simulating electromagnets.

Two repos; publish Rust crate and Python lib separately.

Off-the-shelf CI:
- Rust: release-plz and cargo-semver-checks (SemVer linting reduces downstream debugging at near-zero cost!)
- Python: PyO3/maturin, mixed native project

One-line build

Downsides are fairly minor (duplicating documentation, split repos)

When to push features back from Python to Rust?
- NOT "when I will save more time in my current workflow than it takes to rewrite"
- Workflows change with performance: "What would you do if it were faster, that isn't being done now?"

Prototype in Python/numpy (??? hrs), then rewrite it in Rust (15min - 2hrs), then add bindings back to Python (15-45min to write PyO3 Rust glue, ~15min to write symmetric Python bindings)
110
Predrag Gruevski @predr.ag · 24/07/2024
We interrupt your scrolling to bring you: ✨ a new cargo-semver-checks release ✨
v0.33.0

In this release:
- lint configuration
- a new lint
- support for rustdoc format v32

This release requires Rust 1.74+ both to install (MSRV) and at runtime. This is the last release to support Rust 1.74-1.76; future releases will require Rust 1.77+.

* Lint configuration

Thanks to @suaviloquence's hard work as part of our participation in Google Summer of Code, users can now customize the SemVer (major/minor/patch) and severity (error/warn/allow) levels of cargo-semver-checks lints 🎉

While we've already extensively tested this feature, we know that complex new code often reveals surprises when it first faces the real world. Please kindly report any bugs or reach out in the GSoC project's Zulip if you have questions or concerns.

Read more about this new feature on @suaviloquence's blog: https://blog.mcarr.one/
120