{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreif4yr2orljzw2nye3et75bxtvhsgjrlgnfqajw7pskhzak2luhnie",
    "uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mfvltlz3kfn2"
  },
  "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"
}