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 DebugBreak,
33 Internal(String),
34}
35
36impl fmt::Display for FunctionalError {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 match self {
39 Self::Io(s) => write!(f, "io: {s}"),
40 Self::Parse(s) => write!(f, "parse: {s}"),
41 Self::Unsupported { detail } => write!(f, "unsupported: {detail}"),
42 Self::Validation { detail } => write!(f, "validation: {detail}"),
43 Self::Bounds {
44 addr,
45 size,
46 arena_len,
47 } => write!(
48 f,
49 "bounds: addr={addr:#x} size={size} arena_len={arena_len}"
50 ),
51 Self::UndefinedReg { name } => write!(f, "undefined register '{name}'"),
52 Self::StepBudgetExceeded { steps } => {
53 write!(f, "step budget exceeded after {steps} steps")
54 }
55 Self::Sanitize(finding) => write!(
56 f,
57 "sanitize: {:?} space={:?} addr={:#x} detail={}",
58 finding.kind, finding.space, finding.addr, finding.detail
59 ),
60 Self::DebugBreak => write!(f, "debug: breakpoint"),
61 Self::Internal(s) => write!(f, "internal: {s}"),
62 }
63 }
64}
65
66impl std::error::Error for FunctionalError {}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn display_covers_variants() {
74 let cases = [
75 FunctionalError::Io("x".into()),
76 FunctionalError::Parse("p".into()),
77 FunctionalError::Unsupported { detail: "u".into() },
78 FunctionalError::Validation { detail: "v".into() },
79 FunctionalError::Bounds {
80 addr: 0x10,
81 size: 4,
82 arena_len: 2,
83 },
84 FunctionalError::UndefinedReg { name: "r0".into() },
85 FunctionalError::StepBudgetExceeded { steps: 9 },
86 FunctionalError::Sanitize(crate::sanitize::Finding {
87 kind: crate::sanitize::FindingKind::Race,
88 space: crate::ir::AddrSpace::Global,
89 addr: 0,
90 size: 4,
91 step: 1,
92 barrier_gen: 0,
93 actor: crate::sanitize::WorkItemId {
94 workgroup: [0, 0, 0],
95 wave: 0,
96 lane: 0,
97 flat_local: 0,
98 },
99 other: None,
100 detail: "t".into(),
101 }),
102 FunctionalError::DebugBreak,
103 FunctionalError::Internal("i".into()),
104 ];
105 for err in cases {
106 let s = err.to_string();
107 assert!(!s.is_empty(), "{err:?}");
108 }
109 }
110}