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