softgpu_functional/
error.rs1use crate::sanitize::Finding;
4use std::fmt;
5
6pub type Result<T> = std::result::Result<T, FunctionalError>;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum FunctionalError {
10 Io(String),
11 Parse(String),
12 Unsupported {
13 detail: String,
14 },
15 Validation {
16 detail: String,
17 },
18 Bounds {
19 addr: u64,
20 size: usize,
21 arena_len: usize,
22 },
23 UndefinedReg {
24 name: String,
25 },
26 StepBudgetExceeded {
27 steps: u64,
28 },
29 Sanitize(Finding),
31 Internal(String),
32}
33
34impl fmt::Display for FunctionalError {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 match self {
37 Self::Io(s) => write!(f, "io: {s}"),
38 Self::Parse(s) => write!(f, "parse: {s}"),
39 Self::Unsupported { detail } => write!(f, "unsupported: {detail}"),
40 Self::Validation { detail } => write!(f, "validation: {detail}"),
41 Self::Bounds {
42 addr,
43 size,
44 arena_len,
45 } => write!(
46 f,
47 "bounds: addr={addr:#x} size={size} arena_len={arena_len}"
48 ),
49 Self::UndefinedReg { name } => write!(f, "undefined register '{name}'"),
50 Self::StepBudgetExceeded { steps } => {
51 write!(f, "step budget exceeded after {steps} steps")
52 }
53 Self::Sanitize(finding) => write!(
54 f,
55 "sanitize: {:?} space={:?} addr={:#x} detail={}",
56 finding.kind, finding.space, finding.addr, finding.detail
57 ),
58 Self::Internal(s) => write!(f, "internal: {s}"),
59 }
60 }
61}
62
63impl std::error::Error for FunctionalError {}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn display_covers_variants() {
71 let cases = [
72 FunctionalError::Io("x".into()),
73 FunctionalError::Parse("p".into()),
74 FunctionalError::Unsupported { detail: "u".into() },
75 FunctionalError::Validation { detail: "v".into() },
76 FunctionalError::Bounds {
77 addr: 0x10,
78 size: 4,
79 arena_len: 2,
80 },
81 FunctionalError::UndefinedReg { name: "r0".into() },
82 FunctionalError::StepBudgetExceeded { steps: 9 },
83 FunctionalError::Sanitize(crate::sanitize::Finding {
84 kind: crate::sanitize::FindingKind::Race,
85 space: crate::ir::AddrSpace::Global,
86 addr: 0,
87 size: 4,
88 step: 1,
89 barrier_gen: 0,
90 actor: crate::sanitize::WorkItemId {
91 workgroup: [0, 0, 0],
92 wave: 0,
93 lane: 0,
94 flat_local: 0,
95 },
96 other: None,
97 detail: "t".into(),
98 }),
99 FunctionalError::Internal("i".into()),
100 ];
101 for err in cases {
102 let s = err.to_string();
103 assert!(!s.is_empty(), "{err:?}");
104 }
105 }
106}