Constants can contain references that are not Sync #49206
Open
Description
opened on Mar 20, 2018
This compiles (playground):
#![feature(negative_impls)]
#[derive(Debug)]
struct Foo {
value: u32,
}
impl !std::marker::Sync for Foo {}
fn inspect() {
let foo: &'static Foo = &Foo { value: 1 };
println!(
"I am in thread {:?}, address: {:p}",
std::thread::current().id(),
foo as *const Foo,
);
}
fn main() {
let handle = std::thread::spawn(inspect);
inspect();
handle.join().unwrap();
}
And prints this (addresses vary, but always the same):
I am in thread ThreadId(0), address: 0x5590409f7adc
I am in thread ThreadId(1), address: 0x5590409f7adc
Which shows that two threads get the same 'static
reference to non-Sync
struct.
The problem is that promotion to static does not check if the type is Sync
, while doing it manually does (this does not compile):
static PROMOTED: Foo = Foo { value: 1 };
let foo = &PROMOTED;
Reading the RFC, it seems that the relevant condition is about containing UnsafeCell
, but does not account for other !Sync
types, which are also not supposed to be shared across treads.
Metadata
Assignees
Labels
Area: Constant evaluation, covers all const contexts (static, const fn, ...)Category: This is a bug.#![feature(negative_impls)]Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessMedium priorityStatus: This bug is tracked inside the repo by a `known-bug` test.Relevant to the compiler team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.
Type
Projects
Status
unknown
Activity