naga/front/spv/
error.rs

1use alloc::{
2    format,
3    string::{String, ToString},
4};
5
6use codespan_reporting::diagnostic::Diagnostic;
7use codespan_reporting::files::SimpleFile;
8use codespan_reporting::term;
9
10use super::ModuleState;
11#[cfg(feature = "stderr")]
12use crate::error::ErrorWrite;
13use crate::{arena::Handle, error::replace_control_chars, front::atomic_upgrade};
14
15#[derive(Clone, Debug, thiserror::Error)]
16pub enum Error {
17    #[error("invalid header")]
18    InvalidHeader,
19    #[error("invalid word count")]
20    InvalidWordCount,
21    #[error("unknown instruction {0}")]
22    UnknownInstruction(u16),
23    #[error("unknown capability %{0}")]
24    UnknownCapability(spirv::Word),
25    #[error("unsupported instruction {1:?} at {0:?}")]
26    UnsupportedInstruction(ModuleState, spirv::Op),
27    #[error("unsupported capability {0:?}")]
28    UnsupportedCapability(spirv::Capability),
29    #[error("unsupported extension {0}")]
30    UnsupportedExtension(String),
31    #[error("unsupported extension set {0}")]
32    UnsupportedExtSet(String),
33    #[error("unsupported extension instantiation set %{0}")]
34    UnsupportedExtInstSet(spirv::Word),
35    #[error("unsupported extension instantiation %{0}")]
36    UnsupportedExtInst(spirv::Word),
37    #[error("unsupported type {0:?}")]
38    UnsupportedType(Handle<crate::Type>),
39    #[error("unsupported execution model %{0}")]
40    UnsupportedExecutionModel(spirv::Word),
41    #[error("unsupported execution mode %{0}")]
42    UnsupportedExecutionMode(spirv::Word),
43    #[error("unsupported storage class %{0}")]
44    UnsupportedStorageClass(spirv::Word),
45    #[error("unsupported image dimension %{0}")]
46    UnsupportedImageDim(spirv::Word),
47    #[error("unsupported image format %{0}")]
48    UnsupportedImageFormat(spirv::Word),
49    #[error("unsupported builtin %{0}")]
50    UnsupportedBuiltIn(spirv::Word),
51    #[error("unsupported control flow %{0}")]
52    UnsupportedControlFlow(spirv::Word),
53    #[error("unsupported binary operator %{0}")]
54    UnsupportedBinaryOperator(spirv::Word),
55    #[error("Naga supports OpTypeRuntimeArray in the StorageBuffer storage class only")]
56    UnsupportedRuntimeArrayStorageClass,
57    #[error(
58        "unsupported matrix stride {} for a {}x{} matrix with scalar width={}",
59        stride,
60        columns,
61        rows,
62        width
63    )]
64    UnsupportedMatrixStride {
65        stride: u32,
66        columns: u8,
67        rows: u8,
68        width: u8,
69    },
70    #[error("unknown binary operator {0:?}")]
71    UnknownBinaryOperator(spirv::Op),
72    #[error("unknown relational function {0:?}")]
73    UnknownRelationalFunction(spirv::Op),
74    #[error("unsupported group operation %{0}")]
75    UnsupportedGroupOperation(spirv::Word),
76    #[error("invalid parameter {0:?}")]
77    InvalidParameter(spirv::Op),
78    #[error("invalid operand count {1} for {0:?}")]
79    InvalidOperandCount(spirv::Op, u16),
80    #[error("invalid operand")]
81    InvalidOperand,
82    #[error("invalid id %{0}")]
83    InvalidId(spirv::Word),
84    #[error("invalid decoration %{0}")]
85    InvalidDecoration(spirv::Word),
86    #[error("invalid type width %{0}")]
87    InvalidTypeWidth(spirv::Word),
88    #[error("invalid sign %{0}")]
89    InvalidSign(spirv::Word),
90    #[error("invalid inner type %{0}")]
91    InvalidInnerType(spirv::Word),
92    #[error("invalid vector size %{0}")]
93    InvalidVectorSize(spirv::Word),
94    #[error("invalid access type %{0}")]
95    InvalidAccessType(spirv::Word),
96    #[error("invalid access {0:?}")]
97    InvalidAccess(crate::Expression),
98    #[error("invalid access index %{0}")]
99    InvalidAccessIndex(spirv::Word),
100    #[error("invalid index type %{0}")]
101    InvalidIndexType(spirv::Word),
102    #[error("invalid binding %{0}")]
103    InvalidBinding(spirv::Word),
104    #[error("invalid global var {0:?}")]
105    InvalidGlobalVar(crate::Expression),
106    #[error("invalid image/sampler expression {0:?}")]
107    InvalidImageExpression(crate::Expression),
108    #[error("cannot create a OpTypeImage as both a depth and storage image")]
109    InvalidImageDepthStorage,
110    #[error("image read/write without format is not currently supported. See https://github.com/gfx-rs/wgpu/issues/6797")]
111    InvalidStorageImageWithoutFormat,
112    #[error("invalid image base type {0:?}")]
113    InvalidImageBaseType(Handle<crate::Type>),
114    #[error("invalid image {0:?}")]
115    InvalidImage(Handle<crate::Type>),
116    #[error("invalid as type {0:?}")]
117    InvalidAsType(Handle<crate::Type>),
118    #[error("invalid vector type {0:?}")]
119    InvalidVectorType(Handle<crate::Type>),
120    #[error("inconsistent comparison sampling {0:?}")]
121    InconsistentComparisonSampling(Handle<crate::GlobalVariable>),
122    #[error("wrong function result type %{0}")]
123    WrongFunctionResultType(spirv::Word),
124    #[error("wrong function argument type %{0}")]
125    WrongFunctionArgumentType(spirv::Word),
126    #[error("missing decoration {0:?}")]
127    MissingDecoration(spirv::Decoration),
128    #[error("bad string")]
129    BadString,
130    #[error("incomplete data")]
131    IncompleteData,
132    #[error("invalid terminator")]
133    InvalidTerminator,
134    #[error("invalid edge classification")]
135    InvalidEdgeClassification,
136    #[error("cycle detected in the CFG during traversal at {0}")]
137    ControlFlowGraphCycle(crate::front::spv::BlockId),
138    #[error("recursive function call %{0}")]
139    FunctionCallCycle(spirv::Word),
140    #[error("invalid array size %{0}")]
141    InvalidArraySize(spirv::Word),
142    #[error("invalid barrier scope %{0}")]
143    InvalidBarrierScope(spirv::Word),
144    #[error("invalid barrier memory semantics %{0}")]
145    InvalidBarrierMemorySemantics(spirv::Word),
146    #[error(
147        "arrays of images / samplers are supported only through bindings for \
148         now (i.e. you can't create an array of images or samplers that doesn't \
149         come from a binding)"
150    )]
151    NonBindingArrayOfImageOrSamplers,
152    #[error("naga only supports specialization constant IDs up to 65535 but was given {0}")]
153    SpecIdTooHigh(u32),
154
155    #[error("atomic upgrade error: {0}")]
156    AtomicUpgradeError(atomic_upgrade::Error),
157}
158
159impl Error {
160    #[cfg(feature = "stderr")]
161    pub fn emit_to_writer(&self, writer: &mut impl ErrorWrite, source: &str) {
162        self.emit_to_writer_with_path(writer, source, "spv");
163    }
164
165    #[cfg(feature = "stderr")]
166    pub fn emit_to_writer_with_path(&self, writer: &mut impl ErrorWrite, source: &str, path: &str) {
167        let path = path.to_string();
168        let files = SimpleFile::new(path, replace_control_chars(source));
169        let config = term::Config::default();
170        let diagnostic = Diagnostic::error().with_message(format!("{self:?}"));
171
172        crate::error::emit_to_writer(writer, &config, &files, &diagnostic)
173            .expect("cannot write error");
174    }
175
176    pub fn emit_to_string(&self, source: &str) -> String {
177        self.emit_to_string_with_path(source, "spv")
178    }
179
180    pub fn emit_to_string_with_path(&self, source: &str, path: &str) -> String {
181        let path = path.to_string();
182        let files = SimpleFile::new(path, replace_control_chars(source));
183        let config = term::Config::default();
184        let diagnostic = Diagnostic::error().with_message(format!("{self:?}"));
185
186        let mut writer = crate::error::DiagnosticBuffer::new();
187        writer
188            .emit_to_self(&config, &files, &diagnostic)
189            .expect("cannot write error");
190        writer.into_string()
191    }
192}
193
194impl From<atomic_upgrade::Error> for Error {
195    fn from(source: atomic_upgrade::Error) -> Self {
196        Error::AtomicUpgradeError(source)
197    }
198}