-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Silent failure of std::sync::Once when in const variable #132028
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This code is behaving correctly but unintuitively. A const value behaves "as-if" it is copied in at every usage point, so each call gets a fresh Once to work with. I agree that this is a potential papercut. Ideally, there would be a clippy lint to detect any std::sync or std::cell type in a const, since it a static may have been intended instead. |
@juntyr |
That’s great, thank you for pointing out that it already exists! |
Didn't know about the clippy lint, it definitely would have immediately indicated this problem to me. So, is the fact that |
The FnOnce is technically only called once. The issue is that because you are using a const, every time you name it (in your two calls), it’s as if you had pasted the const initialisation code to this usage to construct a fresh LazyLock with a fresh FnOnce that is then only called this once. On the next usage of the const, you are referring to a completely unrelated LazyLock with a completely unrelated FnOnce. Again, this is unintuitive but the fully correct behaviour of consts, since they by definition have no state that can change at runtime. Perhaps the docs of these types could have an extra warning to call out this papercut specifically? |
Yeah... it definitely feels bad. The explanation makes sense, and leaves me with the question, "why would anyone want to do this?" It seems to me that anyone using [append] |
Agreed. I’ve personally used them in consts but only for type level trickery where I was absolutely sure of what I was doing. So making the lint a bit more on the nose (e.g. by up streaming it from clippy to rustc) would likely avoid many logic bugs while not being too annoying in the few cases where we do need locks and cells in consts. |
The rustc warn by default |
I tried this code playground link:
The problem is that my Once is in a
const
and not astatic
. However, I would expect a compile error or a runtime error instead of broken behavior here. The same behavior is exhibited instd::sync::LazyLock
and probablystd::sync::OnceLock
, due to using a Once internally.Thanks for considering this!
Meta
Checked on 1.82.0 and on nightly.
The text was updated successfully, but these errors were encountered: