Skip to main content

wgsl_types/
error.rs

1use crate::{
2    CallSignature, Type,
3    inst::LiteralInstance,
4    syntax::{BinaryOperator, UnaryOperator},
5};
6
7/// The global error struct.
8#[derive(Clone, Debug)]
9pub enum Error {
10    Todo(String),
11    Unreachable,
12
13    // types & templates
14    NotScalar(Type),
15    NotConstructible(Type),
16    SampledType(Type),
17    UnknownType(String),
18    UnexpectedTemplate(String),
19    MissingTemplate(&'static str),
20
21    // references
22    WriteRefType(Type, Type),
23    NotWrite,
24    NotRead,
25    NotReadWrite,
26    PtrHandle,
27    PtrVecComp,
28
29    // conversions
30    Conversion(Type, Type),
31    ConvOverflow(LiteralInstance, Type),
32
33    // indexing
34    Component(Type, String),
35    NotIndexable(Type),
36    OutOfBounds(usize, Type, usize),
37
38    // arithmetic
39    Unary(UnaryOperator, Type),
40    Binary(BinaryOperator, Type, Type),
41    CompwiseBinary(Type, Type),
42    AddOverflow,
43    SubOverflow,
44    MulOverflow,
45    DivByZero,
46    RemZeroDiv,
47    ShlOverflow(u32, LiteralInstance),
48    ShrOverflow(u32, LiteralInstance),
49
50    // functions
51    Signature(CallSignature),
52    Builtin(&'static str),
53    TemplateArgs(&'static str),
54    ParamCount(String, usize, usize),
55    ParamType(Type, Type),
56}
57
58impl std::fmt::Display for Error {
59    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
60        match self {
61            Error::Todo(v) => write!(fmt, "not implemented: `{v}`"),
62            Error::Unreachable => write!(fmt, "unreachable code detected"),
63            Error::NotScalar(ty) => write!(fmt, "expected a scalar type, got `{ty}`"),
64            Error::NotConstructible(ty) => write!(fmt, "`{ty}` is not constructible"),
65            Error::SampledType(ty) => write!(
66                fmt,
67                "invalid sampled type, expected `i32`, `u32` or `f32`, got `{ty}`"
68            ),
69            Error::UnknownType(ty) => {
70                write!(fmt, "unknown type `{ty}`")
71            }
72            Error::UnexpectedTemplate(ty) => {
73                write!(fmt, "type `{ty}` does not take any template arguments")
74            }
75            Error::MissingTemplate(ty) => write!(fmt, "missing template arguments for type `{ty}`"),
76            Error::WriteRefType(new_ty, ty) => {
77                write!(fmt, "cannot write a `{new_ty}` to a reference to `{ty}`")
78            }
79            Error::NotWrite => write!(fmt, "attempt to write to a read-only reference"),
80            Error::NotRead => write!(fmt, "attempt to read a write-only reference"),
81            Error::NotReadWrite => write!(fmt, "reference is not read-write"),
82            Error::PtrHandle => write!(fmt, "cannot create a pointer in `handle` address space"),
83            Error::PtrVecComp => write!(fmt, "cannot create a pointer to a vector component"),
84            Error::Conversion(from_ty, to_ty) => {
85                write!(fmt, "cannot convert from `{from_ty}` to `{to_ty}`")
86            }
87            Error::ConvOverflow(literal, ty) => {
88                write!(fmt, "overflow while converting `{literal}` to `{ty}`")
89            }
90            Error::Component(ty, name) => write!(fmt, "`{ty}` has no component `{name}`"),
91            Error::NotIndexable(ty) => write!(fmt, "`{ty}` cannot be indexed"),
92            Error::OutOfBounds(index, ty, num_components) => write!(
93                fmt,
94                "index `{index}` is out-of-bounds for `{ty}` of `{num_components}` components"
95            ),
96            Error::Unary(op, ty) => write!(fmt, "cannot use unary operator `{op}` on type `{ty}`"),
97            Error::Binary(op, left_ty, right_ty) => write!(
98                fmt,
99                "cannot use binary operator `{op}` with operands `{left_ty}` and `{right_ty}`"
100            ),
101            Error::CompwiseBinary(ty_1, ty_2) => write!(
102                fmt,
103                "cannot apply component-wise binary operation on operands `{ty_1}` and `{ty_2}`"
104            ),
105            Error::AddOverflow => write!(fmt, "attempt to add with overflow"),
106            Error::SubOverflow => write!(fmt, "attempt to subtract with overflow"),
107            Error::MulOverflow => write!(fmt, "attempt to multiply with overflow"),
108            Error::DivByZero => write!(fmt, "attempt to divide by zero"),
109            Error::RemZeroDiv => write!(
110                fmt,
111                "attempt to calculate the remainder with a divisor of zero"
112            ),
113            Error::ShlOverflow(num, ty) => write!(
114                fmt,
115                "attempt to shift left by `{num}`, which would overflow `{ty}`"
116            ),
117            Error::ShrOverflow(num, ty) => write!(
118                fmt,
119                "attempt to shift right by `{num}`, which would overflow `{ty}`"
120            ),
121            Error::Signature(call_signature) => {
122                write!(fmt, "invalid function call signature: `{call_signature}`")
123            }
124            Error::Builtin(name) => write!(fmt, "{name}"),
125            Error::TemplateArgs(name) => write!(fmt, "invalid template arguments to `{name}`"),
126            Error::ParamCount(name, expected_count, actual_count) => write!(
127                fmt,
128                "incorrect number of arguments to `{name}`, expected `{expected_count}`, got `{actual_count}`"
129            ),
130            Error::ParamType(expected_ty, actual_ty) => write!(
131                fmt,
132                "invalid parameter type, expected `{expected_ty}`, got `{actual_ty}`"
133            ),
134        }
135    }
136}