use alloc::{ format, string::{String, ToString}, }; use codespan_reporting::diagnostic::Diagnostic; use codespan_reporting::files::SimpleFile; use codespan_reporting::term; use super::ModuleState; use crate::{ arena::Handle, error::{replace_control_chars, ErrorWrite}, front::atomic_upgrade, }; #[derive(Clone, Debug, thiserror::Error)] pub enum Error { #[error("invalid header")] InvalidHeader, #[error("invalid word count")] InvalidWordCount, #[error("unknown instruction {0}")] UnknownInstruction(u16), #[error("unknown capability %{0}")] UnknownCapability(spirv::Word), #[error("unsupported instruction {1:?} at {0:?}")] UnsupportedInstruction(ModuleState, spirv::Op), #[error("unsupported capability {0:?}")] UnsupportedCapability(spirv::Capability), #[error("unsupported extension {0}")] UnsupportedExtension(String), #[error("unsupported extension set {0}")] UnsupportedExtSet(String), #[error("unsupported extension instantiation set %{0}")] UnsupportedExtInstSet(spirv::Word), #[error("unsupported extension instantiation %{0}")] UnsupportedExtInst(spirv::Word), #[error("unsupported type {0:?}")] UnsupportedType(Handle), #[error("unsupported execution model %{0}")] UnsupportedExecutionModel(spirv::Word), #[error("unsupported execution mode %{0}")] UnsupportedExecutionMode(spirv::Word), #[error("unsupported storage class %{0}")] UnsupportedStorageClass(spirv::Word), #[error("unsupported image dimension %{0}")] UnsupportedImageDim(spirv::Word), #[error("unsupported image format %{0}")] UnsupportedImageFormat(spirv::Word), #[error("unsupported builtin %{0}")] UnsupportedBuiltIn(spirv::Word), #[error("unsupported control flow %{0}")] UnsupportedControlFlow(spirv::Word), #[error("unsupported binary operator %{0}")] UnsupportedBinaryOperator(spirv::Word), #[error("Naga supports OpTypeRuntimeArray in the StorageBuffer storage class only")] UnsupportedRuntimeArrayStorageClass, #[error( "unsupported matrix stride {} for a {}x{} matrix with scalar width={}", stride, columns, rows, width )] UnsupportedMatrixStride { stride: u32, columns: u8, rows: u8, width: u8, }, #[error("unknown binary operator {0:?}")] UnknownBinaryOperator(spirv::Op), #[error("unknown relational function {0:?}")] UnknownRelationalFunction(spirv::Op), #[error("unsupported group operation %{0}")] UnsupportedGroupOperation(spirv::Word), #[error("invalid parameter {0:?}")] InvalidParameter(spirv::Op), #[error("invalid operand count {1} for {0:?}")] InvalidOperandCount(spirv::Op, u16), #[error("invalid operand")] InvalidOperand, #[error("invalid id %{0}")] InvalidId(spirv::Word), #[error("invalid decoration %{0}")] InvalidDecoration(spirv::Word), #[error("invalid type width %{0}")] InvalidTypeWidth(spirv::Word), #[error("invalid sign %{0}")] InvalidSign(spirv::Word), #[error("invalid inner type %{0}")] InvalidInnerType(spirv::Word), #[error("invalid vector size %{0}")] InvalidVectorSize(spirv::Word), #[error("invalid access type %{0}")] InvalidAccessType(spirv::Word), #[error("invalid access {0:?}")] InvalidAccess(crate::Expression), #[error("invalid access index %{0}")] InvalidAccessIndex(spirv::Word), #[error("invalid index type %{0}")] InvalidIndexType(spirv::Word), #[error("invalid binding %{0}")] InvalidBinding(spirv::Word), #[error("invalid global var {0:?}")] InvalidGlobalVar(crate::Expression), #[error("invalid image/sampler expression {0:?}")] InvalidImageExpression(crate::Expression), #[error("image write without format is not currently supported. See https://github.com/gfx-rs/wgpu/issues/6797")] InvalidImageWriteType, #[error("invalid image base type {0:?}")] InvalidImageBaseType(Handle), #[error("invalid image {0:?}")] InvalidImage(Handle), #[error("invalid as type {0:?}")] InvalidAsType(Handle), #[error("invalid vector type {0:?}")] InvalidVectorType(Handle), #[error("inconsistent comparison sampling {0:?}")] InconsistentComparisonSampling(Handle), #[error("wrong function result type %{0}")] WrongFunctionResultType(spirv::Word), #[error("wrong function argument type %{0}")] WrongFunctionArgumentType(spirv::Word), #[error("missing decoration {0:?}")] MissingDecoration(spirv::Decoration), #[error("bad string")] BadString, #[error("incomplete data")] IncompleteData, #[error("invalid terminator")] InvalidTerminator, #[error("invalid edge classification")] InvalidEdgeClassification, #[error("cycle detected in the CFG during traversal at {0}")] ControlFlowGraphCycle(crate::front::spv::BlockId), #[error("recursive function call %{0}")] FunctionCallCycle(spirv::Word), #[error("invalid array size %{0}")] InvalidArraySize(spirv::Word), #[error("invalid barrier scope %{0}")] InvalidBarrierScope(spirv::Word), #[error("invalid barrier memory semantics %{0}")] InvalidBarrierMemorySemantics(spirv::Word), #[error( "arrays of images / samplers are supported only through bindings for \ now (i.e. you can't create an array of images or samplers that doesn't \ come from a binding)" )] NonBindingArrayOfImageOrSamplers, #[error("naga only supports specialization constant IDs up to 65535 but was given {0}")] SpecIdTooHigh(u32), #[error("atomic upgrade error: {0}")] AtomicUpgradeError(atomic_upgrade::Error), } impl Error { pub fn emit_to_writer(&self, writer: &mut impl ErrorWrite, source: &str) { self.emit_to_writer_with_path(writer, source, "glsl"); } pub fn emit_to_writer_with_path(&self, writer: &mut impl ErrorWrite, source: &str, path: &str) { let path = path.to_string(); let files = SimpleFile::new(path, replace_control_chars(source)); let config = term::Config::default(); let diagnostic = Diagnostic::error().with_message(format!("{self:?}")); term::emit(writer, &config, &files, &diagnostic).expect("cannot write error"); } pub fn emit_to_string(&self, source: &str) -> String { let mut writer = crate::error::DiagnosticBuffer::new(); self.emit_to_writer(writer.inner_mut(), source); writer.into_string() } } impl From for Error { fn from(source: atomic_upgrade::Error) -> Self { Error::AtomicUpgradeError(source) } }