{"record":{"id":"eeabacb6370435db","repo":"gfx-rs/wgpu","slug":"not-implemented-eeabac","errorCode":null,"errorMessage":"not implemented","messagePattern":"not implemented","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"naga/src/back/msl/writer.rs","lineNumber":669,"sourceCode":"            | Self::WorkGroup\n            | Self::Immediate\n            | Self::Handle\n            | Self::TaskPayload => true,\n            Self::Function => false,\n            Self::RayPayload | Self::IncomingRayPayload => unreachable!(),\n        }\n    }\n\n    /// Returns true if the address space may need a \"const\" qualifier.\n    const fn needs_access_qualifier(&self) -> bool {\n        match *self {\n            //Note: we are ignoring the storage access here, and instead\n            // rely on the actual use of a global by functions. This means we\n            // may end up with \"const\" even if the binding is read-write,\n            // and that should be OK.\n            Self::Storage { .. } => true,\n            Self::TaskPayload => true,\n            Self::RayPayload | Self::IncomingRayPayload => unimplemented!(),\n            // These should always be read-write.\n            Self::Private | Self::WorkGroup => false,\n            // These translate to `constant` address space, no need for qualifiers.\n            Self::Uniform | Self::Immediate => false,\n            // Not applicable.\n            Self::Handle | Self::Function => false,\n        }\n    }\n\n    const fn to_msl_name(self) -> Option<&'static str> {\n        match self {\n            Self::Handle => None,\n            Self::Uniform | Self::Immediate => Some(\"constant\"),\n            Self::Storage { .. } => Some(\"device\"),\n            // note for `RayPayload`, this probably needs to be emulated as a\n            // private variable, as metal has essentially an inout input\n            // for where it is passed.\n            Self::Private | Self::Function | Self::RayPayload => Some(\"thread\"),","sourceCodeStart":651,"sourceCodeEnd":687,"githubUrl":"https://github.com/gfx-rs/wgpu/blob/3e11ff59bf3f9795d285ecc045014089640d7248/naga/src/back/msl/writer.rs#L651-L687","documentation":"This is a Rust `unimplemented!()` panic raised by naga's Metal (MSL) backend in `needs_access_qualifier`, which decides whether a global variable's address space needs an access qualifier in generated MSL. The MSL writer does not yet know how to classify the `RayPayload` or `IncomingRayPayload` address spaces, so encountering a module whose globals use them panics instead of producing Metal code. It is a capability gap in the backend, not a user error in the shader itself being validated.","triggerScenarios":"Translating a WGSL/SPIR-V module to MSL whose global variables are declared in the `AddressSpace::RayPayload` or `AddressSpace::IncomingRayPayload` address spaces (i.e. any shader using ray tracing payloads), when the code path asks for an access qualifier for that global.","commonSituations":"Developers experimenting with naga's in-progress ray tracing support and targeting Metal; cross-compiling a ray tracing shader that works on a backend with ray payload support (e.g. SPIR-V) down to MSL; enabling ray tracing IR types before the MSL backend caught up.","solutions":["Do not use RayPayload/IncomingRayPayload globals in shaders translated to Metal; restructure to pass payload data via storage buffers.","Check naga's issue tracker/CHANGELOG for MSL ray tracing support status and upgrade naga once implemented.","Detect ray payload address space usage before calling the MSL writer and reject the module with a clear error instead of panicking."],"exampleFix":"// before: module with\nglobal_var: var<ray_payload> Payload p;\n// after (Metal-safe workaround)\nglobal_var: var<storage, read_write> Payload p;","handlingStrategy":"validation","validationCode":"fn uses_ray_payload(module: &naga::Module) -> bool {\n    module.global_variables.iter().any(|(_, v)|\n        matches!(v.space, naga::AddressSpace::RayPayload | naga::AddressSpace::IncomingRayPayload))\n}\n// reject before calling the MSL writer","typeGuard":"fn is_ray_payload(space: &naga::AddressSpace) -> bool {\n    matches!(space, naga::AddressSpace::RayPayload | naga::AddressSpace::IncomingRayPayload)\n}","tryCatchPattern":"// panics are not catchable in Rust; isolate translation in a subprocess or catch_unwind\nlet result = std::panic::catch_unwind(|| naga::msl::write_string(...));","preventionTips":["Pre-scan naga IR for ray tracing address spaces before targeting MSL","Keep naga updated on MSL ray tracing support status","Use catch_unwind or process isolation around backend translation in production pipelines"],"tags":["naga","msl","metal-backend","ray-tracing","unimplemented","panic"],"backgroundTag":"unimplemented-backend-feature","analyzedSha":"3e11ff59bf3f9795d285ecc045014089640d7248","analyzedAt":"2026-09-03T01:43:21.459Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}