External Publication
Visit Post

Impact of Static Variables on API Soundness

Rust Internals [Unofficial] February 26, 2026
Source

For what it’s worth I think the “what about the future” part is a distraction for this question. Normally, yes, I’d be all for looking beyond today to make a better, more stable library for the future. But unsafe functions are those where the caller must guarantee some condition the compiler can’t check for them. Today, your function has no preconditions from the perspective of an outside client. So what are they supposed to check?

Now consider that you add a new API that puts things in a bad state. (I’m intentionally being abstract because I don’t think involving a static is special; the pointer could just as easily be a member variable and you’d still be in this situation.) Now your original function has an uncheckable precondition, and it’s pretty easy to say it should be marked unsafe. That’d be a breaking change if it wasn’t before, because old callers won’t compile.

However, even that’s a red herring. Suppose you documented the precondition as “you must not have called foo() before calling critical()”. And then in the next release you add bar() that can also put things in a bad state. Now your precondition has changed, but (at least with the way unsafe works today) there’s no source break. I’d argue that this is still a semantically breaking change, because the client does not know they have to uphold the new precondition.

You could maybe argue that existing clients can’t be calling bar(), and thus no existing code is broken. That’s probably true for the time being. But without marking it as breaking, they won’t have a reason to see that the preconditions on critical() have changed. I mean, sure, you can read the release notes for non-breaking updates, but it’s not the same—I think a lot of times people would expect cargo update && cargo test to be sufficient.

So even if it’s not technically build-breaking, I think every change to a function’s unchecked preconditions should at least default to being considered breaking, and therefore the idea of designing an unsafe function to be futureproof is not worth it.

Discussion in the ATmosphere

Loading comments...