diff --git a/naga/src/back/wgsl/writer.rs b/naga/src/back/wgsl/writer.rs index e13ab80215..a63217098e 100644 --- a/naga/src/back/wgsl/writer.rs +++ b/naga/src/back/wgsl/writer.rs @@ -1764,6 +1764,10 @@ impl TypeContext for WriterTypeContext<'_> { self.names[&NameKey::Type(handle)].as_str() } + fn write_unnamed_struct(&self, _: &TypeInner, _: &mut W) -> core::fmt::Result { + unreachable!("the WGSL back end should always provide type handles"); + } + fn write_override(&self, _: Handle, _: &mut W) -> core::fmt::Result { unreachable!("overrides should be validated out"); } diff --git a/naga/src/common/wgsl/types.rs b/naga/src/common/wgsl/types.rs index cbc456970b..c118feeace 100644 --- a/naga/src/common/wgsl/types.rs +++ b/naga/src/common/wgsl/types.rs @@ -39,6 +39,14 @@ pub trait TypeContext { out: &mut W, ) -> core::fmt::Result; + /// Write a [`TypeInner::Struct`] for which we are unable to find a name. + /// + /// The names of struct types are only available if we have `Handle`, + /// not from [`TypeInner`]. For logging and debugging, it's fine to just + /// write something helpful to the developer, but for generating WGSL, + /// this should be unreachable. + fn write_unnamed_struct(&self, inner: &TypeInner, out: &mut W) -> core::fmt::Result; + /// Write a [`TypeInner`] that has no representation as WGSL source, /// even including Naga extensions. /// @@ -363,7 +371,7 @@ where write!(out, "acceleration_structure{}", caps)? } TypeInner::Struct { .. } => { - unreachable!("structs can only be referenced by name in WGSL"); + ctx.write_unnamed_struct(inner, out)?; } TypeInner::RayQuery { vertex_return } => { let caps = if vertex_return { "" } else { "" }; @@ -414,6 +422,10 @@ impl TypeContext for crate::proc::GlobalCtx<'_> { .unwrap_or("{anonymous type}") } + fn write_unnamed_struct(&self, _: &TypeInner, out: &mut W) -> core::fmt::Result { + write!(out, "{{unnamed struct}}") + } + fn write_override( &self, handle: Handle, @@ -446,6 +458,10 @@ impl TypeContext for crate::UniqueArena { self[handle].name.as_deref().unwrap_or("{anonymous type}") } + fn write_unnamed_struct(&self, inner: &TypeInner, out: &mut W) -> core::fmt::Result { + write!(out, "{{unnamed struct {inner:?}}}") + } + fn write_override( &self, handle: Handle, diff --git a/naga/src/front/wgsl/lower/mod.rs b/naga/src/front/wgsl/lower/mod.rs index cb1ac387fa..00f222c68d 100644 --- a/naga/src/front/wgsl/lower/mod.rs +++ b/naga/src/front/wgsl/lower/mod.rs @@ -412,6 +412,14 @@ impl TypeContext for ExpressionContext<'_, '_, '_> { None => write!(out, "{{anonymous override {handle:?}}}"), } } + + fn write_unnamed_struct( + &self, + _: &crate::TypeInner, + _: &mut W, + ) -> core::fmt::Result { + unreachable!("the WGSL front end should always know the type name"); + } } impl<'source, 'temp, 'out> ExpressionContext<'source, 'temp, 'out> {