{"id":"0569bfdaaad7332f","repo":"rust-lang/rust","slug":"static-addr-of-mut-did-not-add-the-global-to-se","errorCode":null,"errorMessage":"`static_addr_of_mut` did not add the global to `self.global_lvalues`","messagePattern":"`static_addr_of_mut` did not add the global to `self\\.global_lvalues`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_codegen_gcc/src/consts.rs","lineNumber":77,"sourceCode":"    fn static_addr_of(&self, alloc: ConstAllocation<'_>, kind: Option<&str>) -> RValue<'gcc> {\n        let cv = const_alloc_to_gcc(self, alloc);\n        let align = alloc.inner().align;\n\n        if let Some(variable) = self.const_globals.borrow().get(&cv) {\n            if let Some(global_variable) = self.global_lvalues.borrow().get(variable) {\n                let alignment = align.bits() as i32;\n                if alignment > global_variable.get_alignment() {\n                    global_variable.set_alignment(alignment);\n                }\n            }\n            return *variable;\n        }\n        let global_value = self.static_addr_of_mut(cv, align, kind);\n        #[cfg(feature = \"master\")]\n        self.global_lvalues\n            .borrow()\n            .get(&global_value)\n            .expect(\"`static_addr_of_mut` did not add the global to `self.global_lvalues`\")\n            .global_set_readonly();\n        self.const_globals.borrow_mut().insert(cv, global_value);\n        global_value\n    }\n\n    fn codegen_static(&mut self, def_id: DefId) {\n        let attrs = self.tcx.codegen_fn_attrs(def_id);\n\n        let Ok((value, alloc)) = codegen_static_initializer(self, def_id) else {\n            // Error has already been reported\n            return;\n        };\n        let alloc = alloc.inner();\n\n        // boolean SSA values are i1, but they have to be stored in i8 slots,\n        // otherwise some LLVM optimization passes don't work as expected\n        let val_llty = self.val_ty(value);\n        if val_llty == self.type_i1() {","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_codegen_gcc/src/consts.rs#L59-L95","documentation":"In `consts.rs:73-78`, when the `master` feature is enabled, `codegen_static_initializer`-adjacent code calls `self.global_lvalues.borrow().get(&global_value).expect(...)` to mark a const global readonly. `static_addr_of_mut` (consts.rs:192-216) is *supposed* to insert the rvalue→global mapping at line 214. The expect fires when that insertion did not happen for the returned rvalue — i.e. the address returned by `global.get_address(None)` is not the key found in `global_lvalues`. This is a defensive invariant check that only compiles with `--cfg feature=\"master\"`.","triggerScenarios":"Compiling with the `master` feature (which enables libgccjit master-branch APIs used in tests/build_system/test.rs) AND a code path where `static_addr_of_mut`'s returned `rvalue` (from `global.get_address(None)`) is not the same key inserted into `global_lvalues`, or where the insert was bypassed/overridden by a custom path. Possible if `get_address` returns a fresh/distinct rvalue identity each call, or if a subclass/replacement of `static_addr_of_mut` skips the insert.","commonSituations":"Seen only on builds with `feature=\"master\"` against a newer libgccjit where `get_address`/global identity semantics changed; local forks that wrap or intercept `static_addr_of_mut`; races from multiple codegen units if `global_lvalues` is unexpectedly shared. On a clean upstream build this should never fire.","solutions":["Confirm you are on a libgccjit version compatible with this rustc_codegen_gcc checkout; `get_address` returning unequal identities across calls is the usual culprit — re-pin libgccjit.","If you have a custom `static_addr_of_mut`, ensure it inserts the *exact* rvalue it returns into `self.global_lvalues` (as the upstream does at consts.rs:214).","Cache the rvalue once: call `global.get_address(None)` a single time and reuse it for both the insert and the return value, avoiding identity drift.","If unavoidable, relax the expect to best-effort (mark readonly only when present) rather than panicking, but treat that as a stopgap and report the invariant break upstream."],"exampleFix":"// before (consts.rs:72-78)\nlet global_value = self.static_addr_of_mut(cv, align, kind);\n#[cfg(feature = \"master\")]\nself.global_lvalues\n    .borrow()\n    .get(&global_value)\n    .expect(\"`static_addr_of_mut` did not add the global to `self.global_lvalues`\")\n    .global_set_readonly();\n\n// after (static_addr_of_mut caches the address once — consts.rs:211-215)\nlet rvalue = global.get_address(None);\nself.global_lvalues.borrow_mut().insert(rvalue, global);\nrvalue  // returned value is guaranteed to be the inserted key","handlingStrategy":"validation","validationCode":"// consts.rs:77 -> invariant: static_addr_of_mut must register the global\n// in self.global_lvalues. This path only runs under the `master` gccjit\n// feature (const_globals/readonly promotion). Sidestep by disabling master\n// or by not promoting a mutable backing value to a readonly const global.\n#[cfg(not(feature = \"master\"))]\nfn compile_with_gcc_backend(cx: &mut CodegenCx) { /* non-master path: assertion gated out */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin to a rustc_codegen_gcc release where static_addr_of_mut reliably registers every global in global_lvalues; the assertion is a known regression on the master-feature path.","Avoid promoting mutable consts to readonly globals while the `master` libgccjit feature is enabled.","This is an internal invariant violation, not a user-input bug - reproduce minimally and file upstream."],"tags":["rustc-codegen-gcc","statics","global-lvalues","master-feature","panic"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}