{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreif4yr2orljzw2nye3et75bxtvhsgjrlgnfqajw7pskhzak2luhnie",
"uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mfu4u3v5twf2"
},
"path": "/t/impact-of-static-variables-on-api-soundness/24039#post_3",
"publishedAt": "2026-02-26T17:59:10.000Z",
"site": "https://internals.rust-lang.org",
"textContent": "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?\n\nNow 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.\n\nHowever, 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.\n\nYou 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.\n\nSo 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.",
"title": "Impact of Static Variables on API Soundness"
}