Skip to content
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

#[thread_local] static mut is allowed to have 'static lifetime #54366

Open
nikomatsakis opened this issue Sep 19, 2018 · 10 comments
Open

#[thread_local] static mut is allowed to have 'static lifetime #54366

nikomatsakis opened this issue Sep 19, 2018 · 10 comments
Labels
A-NLL Area: Non Lexical Lifetimes (NLL) F-thread_local `#![feature(thread_local)]` NLL-sound Working towards the "invalid code does not compile" goal P-medium Medium priority requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Sep 19, 2018

Spinning off from #51269:

The MIR borrow checker (i.e., NLL) permits #[thread_local] static mut to have 'static lifetime. This is probably a bug. It arises because we ignore borrows of "unsafe places", which includes static mut.

We probably ought to stop doing that — at least not ignoring them entirely — but if we do so, we have to ensure that we continue to accept overlapping borrows of static mut (even though that is basically guaranteed UB), since it compiles today:

fn main() {
 static mut X: usize = 22;
 unsafe {
  let p = &mut X;
  let q = &mut X;
  *p += 1;
  *q += 1;
  *p += 1;
 }
}
@nikomatsakis nikomatsakis added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-NLL Area: Non Lexical Lifetimes (NLL) NLL-deferred labels Sep 19, 2018
kennytm added a commit to kennytm/rust that referenced this issue Sep 20, 2018
…borrow-test, r=pnkfelix

Add regression test for thread local static mut borrows

FIXME(rust-lang#54366) - We probably shouldn't allow `#[thread_local] static mut` to get a `'static` lifetime, but for now, we should at least test the behavior that `rustc` currently has.
@pnkfelix
Copy link
Member

Re-triaging for #56754. Based on #29594 (comment) I am tagging this as P-medium.

@pnkfelix pnkfelix added P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. NLL-deferred labels Dec 21, 2018
@nikomatsakis nikomatsakis added the NLL-sound Working towards the "invalid code does not compile" goal label Jan 23, 2019
@matthewjasper matthewjasper added F-thread_local `#![feature(thread_local)]` requires-nightly This issue requires a nightly compiler in some way. labels Aug 11, 2019
@oli-obk
Copy link
Contributor

oli-obk commented Dec 26, 2019

Fixing this issue is easy now, but it will be super hard to do with a future incompat lint, because the real change is happening elsewhere. The fix is to change https://github.com/rust-lang/rust/blob/a916ac22b9f7f1f0f7aba0a41a789b3ecd765018/src/librustc/ty/util.rs#L666.L667 to

if self.is_mutable_static(def_id) {
    self.mk_mut_ref(self.lifetimes.re_erased, static_ty)

Because then borrowck will pick it up correctly and detect the thread local annotation and not give it the static lifetime

@bstrie
Copy link
Contributor

bstrie commented Feb 3, 2020

@oli-obk, is a future incompat lint necessary if this feature is still unstable? It doesn't sound like that change would affect stable users.

@nikomatsakis
Copy link
Contributor Author

I agree a lint is probably not needed. I'm not sure whether I think @oli-obk's suggested patch is correct (like, I literally haven't looked into it -- it probably is).

@oli-obk
Copy link
Contributor

oli-obk commented Apr 16, 2020

While attempting to fix #70685 (see #71192 for the changes) I got all of our tests to pass, except for https://github.com/rust-lang/rust/blob/master/src/test/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.rs which references this issue. I have reinstated the current behaviour, but the site of the required change that I suggested above has changed. It's now in the Rvalue::ty method.

@RalfJung
Copy link
Member

Curiously, doing the same thing with a non-mut static is detected by the borrow checker.

@RalfJung
Copy link
Member

@oli-obk

The fix is to change https://github.com/rust-lang/rust/blob/a916ac22b9f7f1f0f7aba0a41a789b3ecd765018/src/librustc/ty/util.rs#L666.L667 to

Isn't that a problem with unsafety checking? You said elsewhere that this crucially is a raw pointer to ensure that accesses are unsafe.

@oli-obk
Copy link
Contributor

oli-obk commented Nov 20, 2020

We do unsafety checking properly nowadays:

// If the projection root is an artifical local that we introduced when
// desugaring `static`, give a more specific error message
// (avoid the general "raw pointer" clause below, that would only be confusing).
if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
if self.tcx.is_mutable_static(def_id) {
self.require_unsafe(
UnsafetyViolationKind::General,
UnsafetyViolationDetails::UseOfMutableStatic,
);
return;

So the raw pointer checks aren't actually necessary, even though they are a good safety net for our use of LocalInfo for soundness.

@RalfJung
Copy link
Member

"properly" for some notion of "properly". ;) Relying on LocalInfo feels rather fragile.

@VorpalBlade
Copy link

Will this be solved in edition 2024 by the changes to static mut being done? Or will this still be an issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-NLL Area: Non Lexical Lifetimes (NLL) F-thread_local `#![feature(thread_local)]` NLL-sound Working towards the "invalid code does not compile" goal P-medium Medium priority requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants