Open
Description
Consider this piece of code:
use std::sync::atomic::*;
static UNIQ_ID: AtomicU64 = AtomicU64::new(0);
struct Foo(u64);
impl Foo {
fn new() -> Foo {
Foo(UNIQ_ID.fetch_add(1, Ordering::Relaxed))
}
}
impl Drop for Foo {
fn drop(&mut self) {
eprintln!("{} dropped with addr {:p}", self.0, self);
}
}
fn main() {
thread_local!(static FOO: Foo = Foo::new());
FOO.with(|foo| {
eprintln!("{} living with addr {:p}", foo.0, foo);
});
}
I would expect the statically declared FOO
to not move around after initialization. In fact, Foo
might be a type which may not be moved around after initialization at all, such as a type containing pthread_mutex_t
. However, we see that it does get moved before the drop:
0 living with addr 0x6000002000a8
0 dropped with addr 0x16f9faaa8
I believe the issue lies here:
rust/library/std/src/sys/thread_local/native/lazy.rs
Lines 95 to 98 in e964cca
This code should be changed to not use an enum but rather a separate state flag + cell, so that the value is not moved.
Metadata
Metadata
Assignees
Labels
Area: Thread local storage (TLS)Category: Discussion or questions that doesn't represent real issues.Category: A feature request, i.e: not implemented / a PR.Relevant to the library team, which will review and decide on the PR/issue.This issue may need triage. Remove it if it has been sufficiently triaged.