about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-04-02 13:00:46 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-04-02 13:00:46 +0000
commit64b75f736ddaf10887a508941ab7dea9a67d01d4 (patch)
tree112874253d76ae8f8f777800270fa4dcef6388fc
parent6c5c48e880ca0668c5c8a8029769636831985137 (diff)
downloadrust-64b75f736ddaf10887a508941ab7dea9a67d01d4.tar.gz
rust-64b75f736ddaf10887a508941ab7dea9a67d01d4.zip
Forbid implicit nested statics in thread local statics
-rw-r--r--compiler/rustc_const_eval/messages.ftl1
-rw-r--r--compiler/rustc_const_eval/src/errors.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs6
-rw-r--r--tests/ui/statics/nested_thread_local.rs28
-rw-r--r--tests/ui/statics/nested_thread_local.stderr8
5 files changed, 30 insertions, 20 deletions
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index d6aae60c338..f6937dc145d 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -222,6 +222,7 @@ const_eval_mut_deref =
 
 const_eval_mutable_ptr_in_final = encountered mutable pointer in final value of {const_eval_intern_kind}
 
+const_eval_nested_static_in_thread_local = #[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead
 const_eval_non_const_fmt_macro_call =
     cannot call non-const formatting macro in {const_eval_const_context}s
 
diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs
index 5c46ec799f1..a60cedd6500 100644
--- a/compiler/rustc_const_eval/src/errors.rs
+++ b/compiler/rustc_const_eval/src/errors.rs
@@ -25,6 +25,13 @@ pub(crate) struct DanglingPtrInFinal {
     pub kind: InternKind,
 }
 
+#[derive(Diagnostic)]
+#[diag(const_eval_nested_static_in_thread_local)]
+pub(crate) struct NestedStaticInThreadLocal {
+    #[primary_span]
+    pub span: Span,
+}
+
 #[derive(LintDiagnostic)]
 #[diag(const_eval_mutable_ptr_in_final)]
 pub(crate) struct MutablePtrInFinal {
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index f4e46c9499e..d0f0190fea7 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -28,7 +28,7 @@ use rustc_span::sym;
 
 use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, PlaceTy};
 use crate::const_eval;
-use crate::errors::{DanglingPtrInFinal, MutablePtrInFinal};
+use crate::errors::{DanglingPtrInFinal, MutablePtrInFinal, NestedStaticInThreadLocal};
 
 pub trait CompileTimeMachine<'mir, 'tcx: 'mir, T> = Machine<
         'mir,
@@ -108,6 +108,10 @@ fn intern_as_new_static<'tcx>(
     );
     tcx.set_nested_alloc_id_static(alloc_id, feed.def_id());
 
+    if tcx.is_thread_local_static(static_id.into()) {
+        tcx.dcx().emit_err(NestedStaticInThreadLocal { span: tcx.def_span(static_id) });
+    }
+
     // These do not inherit the codegen attrs of the parent static allocation, since
     // it doesn't make sense for them to inherit their `#[no_mangle]` and `#[link_name = ..]`
     // and the like.
diff --git a/tests/ui/statics/nested_thread_local.rs b/tests/ui/statics/nested_thread_local.rs
index 10e0a3420d9..a512016335a 100644
--- a/tests/ui/statics/nested_thread_local.rs
+++ b/tests/ui/statics/nested_thread_local.rs
@@ -1,24 +1,14 @@
-// Check that nested statics in thread locals are
-// duplicated per thread.
+// Check that we forbid nested statics in `thread_local` statics.
 
 #![feature(const_refs_to_cell)]
 #![feature(thread_local)]
 
-//@run-pass
-
 #[thread_local]
-static mut FOO: &mut u32 = &mut 42;
-
-fn main() {
-    unsafe {
-        *FOO = 1;
-
-        let _ = std::thread::spawn(|| {
-            assert_eq!(*FOO, 42);
-            *FOO = 99;
-        })
-        .join();
-
-        assert_eq!(*FOO, 1);
-    }
-}
+static mut FOO: &u32 = {
+    //~^ ERROR: does not support implicit nested statics
+    // Prevent promotion (that would trigger on `&42` as an expression)
+    let x = 42;
+    &{ x }
+};
+
+fn main() {}
diff --git a/tests/ui/statics/nested_thread_local.stderr b/tests/ui/statics/nested_thread_local.stderr
new file mode 100644
index 00000000000..30c742626fa
--- /dev/null
+++ b/tests/ui/statics/nested_thread_local.stderr
@@ -0,0 +1,8 @@
+error: #[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead
+  --> $DIR/nested_thread_local.rs:7:1
+   |
+LL | static mut FOO: &u32 = {
+   | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+