{"record":{"id":"e3f31433ce35447f","repo":"gfx-rs/wgpu","slug":"unexpected-pointer-expression","errorCode":null,"errorMessage":"Unexpected pointer expression {:?}","messagePattern":"Unexpected pointer expression (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"naga/src/back/spv/block.rs","lineNumber":2716,"sourceCode":"                                block,\n                            )?;\n                            self.temp_list.push(index_id);\n                        }\n                    }\n                    base\n                }\n                crate::Expression::GlobalVariable(handle) => {\n                    let gv = &self.writer.global_variables[handle];\n                    break gv.access_id;\n                }\n                crate::Expression::LocalVariable(variable) => {\n                    let local_var = &self.function.variables[&variable];\n                    break local_var.id;\n                }\n                crate::Expression::FunctionArgument(index) => {\n                    break self.function.parameter_id(index);\n                }\n                ref other => unimplemented!(\"Unexpected pointer expression {:?}\", other),\n            }\n        };\n\n        let (pointer_id, expr_pointer) = if self.temp_list.is_empty() {\n            (\n                root_id,\n                ExpressionPointer::Ready {\n                    pointer_id: root_id,\n                },\n            )\n        } else {\n            self.temp_list.reverse();\n            let pointer_id = self.gen_id();\n            let access =\n                Instruction::access_chain(result_type_id, pointer_id, root_id, &self.temp_list);\n\n            // If we generated some bounds checks, we need to leave it to our\n            // caller to generate the branch, the access, the load or store, and","sourceCodeStart":2698,"sourceCodeEnd":2734,"githubUrl":"https://github.com/gfx-rs/wgpu/blob/3e11ff59bf3f9795d285ecc045014089640d7248/naga/src/back/spv/block.rs#L2698-L2734","documentation":"Panic in `write_access_chain` when computing the root of a pointer expression in the SPIR-V backend. The code handles Local/GlobalVariable and FunctionArgument roots; any other expression kind used as a pointer root (e.g. an unexpected intermediate expression after access chains were rewritten) triggers `unimplemented!`. It indicates the backend encountered a pointer form it never expected after earlier lowering passes.","triggerScenarios":"Loading/storing through a pointer whose root expression is not a variable or function argument - typically a function-parameter pointer, complex pointer-from-value expression, or an IR pattern produced by newer frontend features (e.g. pointer dereference chains in WGSL) that this backend path doesn't model.","commonSituations":"Shaders using WGSL pointers (`&var`, pointer function parameters) with a naga version whose SPIR-V writer lacks the pattern; more common in `cache_expression_value`/load paths when the module contains pointer-typed temporaries.","solutions":["Restructure the shader to avoid pointers: pass values by copy or write through the original variable directly","In function bodies, operate on the global/local variable rather than a pointer temporary","Update naga/wgpu - pointer handling in the SPIR-V backend has been actively improved","Reduce the shader and file an issue at github.com/gfx-rs/wgpu"],"exampleFix":"// before (WGSL)\nfn f(p: ptr<function, f32>) { *p = 1.0; }\nlet rp = &v;\n*rp = 1.0;\n// after\nv = 1.0; // operate on the variable directly","handlingStrategy":"try-catch","validationCode":"// scan module expressions for pointer-typed temporaries not rooted in variables/arguments\nfn has_unexpected_pointer_roots(module: &naga::Module) -> bool {\n    module.global_expressions.iter().any(|(_, e)| {\n        matches!(e, naga::Expression::AccessIndex { base, .. } | naga::Expression::Access { base, .. }\n            if matches!(module.globals.get(...), /* base resolves to a non-variable pointer root */ _ => false))\n    })\n}","typeGuard":null,"tryCatchPattern":"let result = std::panic::catch_unwind(|| {\n    naga::back::spv::write_vec(&module, &naga::back::spv::Options::default(), pipeline_constants, &mut writer_flags)\n});\nmatch result {\n    Ok(spirv) => use_spirv(spirv),\n    Err(_) => fallback_to_other_backend_or_report(),\n}","preventionTips":["Avoid WGSL pointer temporaries; write through the original variable","Pass values by copy instead of pointer parameters when targeting SPIR-V","Use a recent naga/wgpu where SPIR-V pointer handling is more complete","Pin and test shader compilation in CI to catch backend gaps early"],"tags":["spirv","shader-compilation","naga","pointers","unimplemented"],"backgroundTag":"unimplemented-shader-feature","analyzedSha":"3e11ff59bf3f9795d285ecc045014089640d7248","analyzedAt":"2026-09-03T01:43:21.459Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}