Skip to main content

workshop_rs/wir/
error.rs

1//! Structured IR errors.
2//!
3//! All fallible IR operations (conversion, validation, lowering) report
4//! [`IrError`] with a stable code and, when the offending source position is
5//! known, a span. Human-readable wording is not part of the stable contract.
6
7use crate::source::Span;
8
9/// A structured IR error.
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum IrError {
12    /// A node reference is dangling or out of range.
13    DanglingReference { what: &'static str, id: u32 },
14    /// A construct the IR does not support, with its source location.
15    Unsupported { message: String, span: Option<Span> },
16    /// A structural or invariant violation.
17    Invalid {
18        code: &'static str,
19        message: String,
20        span: Option<Span>,
21    },
22}
23
24impl IrError {
25    /// Stable machine-readable code.
26    pub fn code(&self) -> &'static str {
27        match self {
28            IrError::DanglingReference { .. } => "dangling-reference",
29            IrError::Unsupported { .. } => "unsupported",
30            IrError::Invalid { code, .. } => code,
31        }
32    }
33
34    /// Human-readable message.
35    pub fn message(&self) -> String {
36        match self {
37            IrError::DanglingReference { what, id } => {
38                format!("dangling {what} reference: id {id}")
39            }
40            IrError::Unsupported { message, .. } => message.clone(),
41            IrError::Invalid { message, .. } => message.clone(),
42        }
43    }
44
45    /// The offending source span, when known.
46    pub fn span(&self) -> Option<Span> {
47        match self {
48            IrError::Unsupported { span, .. } => *span,
49            IrError::Invalid { span, .. } => *span,
50            IrError::DanglingReference { .. } => None,
51        }
52    }
53}
54
55impl std::fmt::Display for IrError {
56    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57        write!(f, "{}: {}", self.code(), self.message())
58    }
59}
60
61impl std::error::Error for IrError {}