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