Allow UnsafeCell in shared statics#152540
Conversation
This is a new trait that is used by the language in bounds for `static` items instead of `Sync`. It is implemented by all `T: Sync`, as well as by `UnsafeCell<T: Sync>`.
The only place where it was required by the language was for checking usage in static variables (and that is now done by `AllowSharedStatic`), all other usage in the compiler was for diagnostics.
|
Some changes occurred in src/tools/clippy cc @rust-lang/clippy This PR modifies cc @jieyouxu Some changes occurred in compiler/rustc_codegen_gcc Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 rust-analyzer is developed in its own repository. If possible, consider making this change to rust-lang/rust-analyzer instead. cc @rust-lang/rust-analyzer |
|
@rustbot label +I-lang-nominated Nominating for t-lang: Do you want to preserve the "shared static" == "requires This would allow writing I guess part of the motivation for this (and |
|
The job Click to see the possible cause of the failure (guessed by this bot) |
| // | ||
| // See also TODO link. | ||
| #[unstable(feature = "allow_shared_static_trait", issue = "none")] | ||
| unsafe impl<T: MetaSized + Sync> AllowSharedStatic for UnsafeCell<T> {} |
There was a problem hiding this comment.
Why does this have a Sync bound on T? The argument for why this is sound (all accesses are unsafe) also work for arbitrary T.
There was a problem hiding this comment.
I intended for this PR to be the minimal first step. We can extend it to T: !Sync later (or during the unstable period).
|
What is the advantage of this over the much simpler |
Simple is in the eye of the beholder. To me, You could argue this PR is a hack too, but then it's just a choice between the least ugly hack ;) (It's also not clear to me from just the name whether As a more general problem, bifurcation of types like this is not without a cost, users are gonna have to learn this new type and crates in the ecosystem like |
|
I claim that this PR is way more ugly hack and in fact, |
|
I think the ideal solution would be a language change that lets me unsafely say "yes I want this static with a |
|
That said -- I also like just using |
Well, me neither, but I guess that's part of what I want to help figure out. |
Background
Using a type in a (shared) static introduces a
Syncbound on that type, to ensure that it is safe to share across threads.This is sufficient, but overly restrictive: there exist other types which are safe to use directly in a static, including
UnsafeCelland raw pointers (these types are!Syncprimarily as a "hint" to avoid items containing them beingSyncvia auto traits, but they are by themselves not unsafe to share across multiple threads).For example
static NULL_INT: *const i32 = std::ptr::null();would be perfectly valid. Another (very contrived) example can be found in this playground.Proposal
I propose special-casing
UnsafeCell<T: Sync>to allow it as the type in shared statics.This would enable the following to compile:
As an alternative to:
While the following would still be an error (because
MyCellis!Sync):Unlike adding an
unsafe impl<T: Sync> Sync for UnsafeCell<T>, this would not be a breaking change as far as I can tell, as library authors shouldn't rely on an arbitraryUnsafeCellnot being shared elsewhere (APIs taking&UnsafeCell<T>can't be safe).This is intended as a partial alternative to
SyncUnsafeCell(tracking issue), which was introduced primarily to avoid having to usestatic mut, and secondarily to avoid the need for a manualSyncimpl. (This PR would make the first item redundant but wouldn't change the second).I have opened rust-lang/reference#2169 to update the reference, to allow you to see how things would look if this was stabilized.
Implementation
This PR introduces a new unstable trait
AllowSharedStaticwhich is now used for the bound on shared statics instead ofSync. It is defined as:This trait is intended to be perma-unstable and not be exposed to users (at least not unless we find a compelling reason to do so). The trait could be implemented for other types in the future (such as
*const T/*mut TorUnsafeCell<T: !Sync>).TODO
Sync's "on_unimplemented" messages, andAllowSharedStaticshouldn't appear in error messages.I will do these if t-lang decides to go forwards with this idea.
r? compiler