about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJubilee <46493976+workingjubilee@users.noreply.github.com>2024-06-05 01:14:32 -0700
committerGitHub <noreply@github.com>2024-06-05 01:14:32 -0700
commit2b89c1b9aeccf748c56bb64584cb70c184edbafa (patch)
treecd09041375f7e6341d57f4deb0b36056126e5175
parent78d9a7e10777317aee44a5154b4c45e5ea55c2a3 (diff)
parent07dc3ebf5c82f1f1420f37d68204600b87522383 (diff)
downloadrust-2b89c1b9aeccf748c56bb64584cb70c184edbafa.tar.gz
rust-2b89c1b9aeccf748c56bb64584cb70c184edbafa.zip
Rollup merge of #125920 - bjorn3:allow_static_mut_linkage_def, r=Urgau
Allow static mut definitions with #[linkage]

Unlike static declarations with #[linkage], for definitions rustc doesn't rewrite it to add an extra indirection.

This was accidentally disallowed in https://github.com/rust-lang/rust/pull/125046.

cc https://github.com/rust-lang/rust/pull/125800#issuecomment-2143776298
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs25
-rw-r--r--tests/ui/linkage-attr/linkage-attr-mutable-static.rs15
-rw-r--r--tests/ui/linkage-attr/linkage-attr-mutable-static.stderr10
3 files changed, 30 insertions, 20 deletions
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 5d7257b15c4..15955170e87 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -324,21 +324,22 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                     let linkage = Some(linkage_by_name(tcx, did, val.as_str()));
                     if tcx.is_foreign_item(did) {
                         codegen_fn_attrs.import_linkage = linkage;
+
+                        if tcx.is_mutable_static(did.into()) {
+                            let mut diag = tcx.dcx().struct_span_err(
+                                attr.span,
+                                "extern mutable statics are not allowed with `#[linkage]`",
+                            );
+                            diag.note(
+                                "marking the extern static mutable would allow changing which symbol \
+                                 the static references rather than make the target of the symbol \
+                                 mutable",
+                            );
+                            diag.emit();
+                        }
                     } else {
                         codegen_fn_attrs.linkage = linkage;
                     }
-                    if tcx.is_mutable_static(did.into()) {
-                        let mut diag = tcx.dcx().struct_span_err(
-                            attr.span,
-                            "mutable statics are not allowed with `#[linkage]`",
-                        );
-                        diag.note(
-                            "making the static mutable would allow changing which symbol the \
-                             static references rather than make the target of the symbol \
-                             mutable",
-                        );
-                        diag.emit();
-                    }
                 }
             }
             sym::link_section => {
diff --git a/tests/ui/linkage-attr/linkage-attr-mutable-static.rs b/tests/ui/linkage-attr/linkage-attr-mutable-static.rs
index a7109c6d930..ed11947f59e 100644
--- a/tests/ui/linkage-attr/linkage-attr-mutable-static.rs
+++ b/tests/ui/linkage-attr/linkage-attr-mutable-static.rs
@@ -4,12 +4,21 @@
 #![feature(linkage)]
 
 fn main() {
+    #[rustfmt::skip]
     extern "C" {
-        #[linkage = "weak"] //~ ERROR mutable statics are not allowed with `#[linkage]`
-        static mut ABC: *const u8;
+        #[linkage = "extern_weak"] //~ ERROR extern mutable statics are not allowed with `#[linkage]`
+        static mut EXTERN_WEAK: *const u8;
     }
 
     unsafe {
-        assert_eq!(ABC as usize, 0);
+        assert_eq!(EXTERN_WEAK as usize, 0);
+    }
+
+    // static mut is fine here as this is a definition rather than declaration.
+    #[linkage = "weak"]
+    static mut WEAK_DEF: u8 = 42;
+
+    unsafe {
+        assert_eq!(WEAK_DEF, 0);
     }
 }
diff --git a/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr b/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr
index 4db41b62393..ad999769047 100644
--- a/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr
+++ b/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr
@@ -1,10 +1,10 @@
-error: mutable statics are not allowed with `#[linkage]`
-  --> $DIR/linkage-attr-mutable-static.rs:8:9
+error: extern mutable statics are not allowed with `#[linkage]`
+  --> $DIR/linkage-attr-mutable-static.rs:9:9
    |
-LL |         #[linkage = "weak"]
-   |         ^^^^^^^^^^^^^^^^^^^
+LL |         #[linkage = "extern_weak"]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: making the static mutable would allow changing which symbol the static references rather than make the target of the symbol mutable
+   = note: marking the extern static mutable would allow changing which symbol the static references rather than make the target of the symbol mutable
 
 error: aborting due to 1 previous error