Skip to main content

tenferro_runtime/program/
error.rs

1/// Errors reported while adding semantic-program structure.
2#[derive(Debug, thiserror::Error)]
3#[non_exhaustive]
4pub enum ProgramBuildError {
5    /// A value token was issued by another builder.
6    #[error("value does not belong to this semantic-program builder")]
7    ForeignValue,
8    /// An import root belongs to another semantic program.
9    #[error("import root does not belong to the source semantic program")]
10    ForeignImportRoot,
11    /// Import bindings were frozen for another semantic program.
12    #[error("import bindings do not belong to the source semantic program")]
13    ForeignBindings,
14    /// Structured control flow is reserved for the later region/block model.
15    #[error("semantic control-flow construct {construct:?} is not supported")]
16    UnsupportedControlFlow {
17        /// Frontend construct that could not be represented.
18        construct: &'static str,
19    },
20    /// A frozen source program failed import-time structural validation.
21    #[error("source semantic program is invalid for import: {source}")]
22    InvalidImport {
23        #[source]
24        source: ProgramStructuralError,
25    },
26    /// A binding target is a computed value rather than an external input.
27    #[error("tensor bindings may target only semantic-program inputs")]
28    BindingTargetNotInput,
29    /// A shape guard target is not produced by a semantic operation.
30    #[error("semantic shape guards may target only operation outputs")]
31    GuardTargetNotOperationOutput,
32    /// An external input already has a tensor binding.
33    #[error("semantic-program input already has a tensor binding")]
34    DuplicateBinding,
35    /// The builder cannot represent another value slot.
36    #[error("semantic-program value count exceeds the supported u32 range")]
37    TooManyValues,
38    /// An operation received the wrong number of SSA inputs.
39    #[error("semantic operation expects {expected} inputs, got {actual}")]
40    Arity {
41        /// Declared input count.
42        expected: usize,
43        /// Supplied input count.
44        actual: usize,
45    },
46    /// Semantic dtype or shape inference failed.
47    #[error("semantic operation metadata inference failed: {source}")]
48    Metadata {
49        /// Original typed runtime inference error.
50        #[source]
51        source: Box<crate::Error>,
52    },
53    /// Inference did not return the declared number of outputs.
54    #[error("semantic operation declares {expected} outputs, inferred {actual}")]
55    OutputMetadataCount {
56        /// Declared output count.
57        expected: usize,
58        /// Inferred metadata count.
59        actual: usize,
60    },
61    /// An extension did not explicitly declare its observable effects.
62    #[error("extension family {family:?} has no semantic effect declaration")]
63    UndeclaredExtensionEffects {
64        /// Stable extension family.
65        family: &'static str,
66    },
67    /// An extension did not explicitly declare output aliases.
68    #[error("extension family {family:?} has no semantic alias declaration")]
69    UndeclaredExtensionAliases {
70        /// Stable extension family.
71        family: &'static str,
72    },
73    /// An extension declared an invalid resource family.
74    #[error("extension family {family:?} declared an invalid effect resource: {source}")]
75    InvalidEffectResource {
76        /// Stable extension family.
77        family: &'static str,
78        /// Typed resource validation failure.
79        #[source]
80        source: EffectResourceError,
81    },
82    /// An alias referenced an input or output outside the operation arity.
83    #[error(
84        "semantic alias index is out of bounds: output {output}/{output_count}, input {input:?}/{input_count}"
85    )]
86    AliasOutOfBounds {
87        /// Referenced output.
88        output: usize,
89        /// Output arity.
90        output_count: usize,
91        /// Referenced input, when applicable.
92        input: Option<usize>,
93        /// Input arity.
94        input_count: usize,
95    },
96    /// An externally defined scalar reached the semantic program.
97    #[error(
98        "externally defined scalar {dtype:?} reached {site} without a canonical program \
99identity; a contribution must declare a stable scalar identity before a traced program can \
100carry it"
101    )]
102    ExternalScalarWithoutIdentity {
103        /// The externally defined tag that reached the program.
104        dtype: tenferro_tensor::DType,
105        /// Where the tag reached the program.
106        site: &'static str,
107    },
108    /// Alias declarations did not cover every output exactly once.
109    #[error("semantic aliases must cover {expected} outputs exactly once, got {actual}")]
110    AliasCoverage {
111        /// Output arity.
112        expected: usize,
113        /// Number of distinct valid output declarations.
114        actual: usize,
115    },
116}
117
118/// Errors reported while querying an immutable semantic program.
119#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
120pub enum ProgramQueryError {
121    /// A value token belongs to another program or names no frozen value.
122    #[error("value does not belong to this semantic program")]
123    ForeignValue,
124}
125
126/// Internal structural validation failures detected during atomic freeze.
127#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
128#[non_exhaustive]
129pub enum ProgramStructuralError {
130    /// An operation references a value outside the frozen value table.
131    #[error("semantic operation references a value outside the program")]
132    InvalidValueReference,
133    /// An operation output is not strictly after all prior values.
134    #[error("semantic operation outputs violate SSA ordering")]
135    InvalidSsaOrder,
136}
137
138/// Tensor-binding validation failures detected during atomic freeze.
139#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
140#[non_exhaustive]
141pub enum ProgramBindingError {
142    /// A pending binding no longer names an external input.
143    #[error("tensor binding target is not a semantic-program input")]
144    InvalidTarget,
145    /// Tensor dtype differs from the input declaration.
146    #[error("tensor binding dtype mismatch: expected {expected:?}, got {actual:?}")]
147    DTypeMismatch {
148        /// Declared input dtype.
149        expected: tenferro_tensor::DType,
150        /// Bound tensor dtype.
151        actual: tenferro_tensor::DType,
152    },
153    /// Tensor rank differs from the input declaration.
154    #[error("tensor binding rank mismatch: expected {expected}, got {actual}")]
155    RankMismatch {
156        /// Declared input rank.
157        expected: usize,
158        /// Bound tensor rank.
159        actual: usize,
160    },
161    /// A statically exact dimension differs from the input declaration.
162    #[error("tensor binding extent mismatch at axis {axis}: expected {expected}, got {actual}")]
163    ExactExtentMismatch {
164        /// Mismatching axis.
165        axis: usize,
166        /// Declared exact extent.
167        expected: usize,
168        /// Bound tensor extent.
169        actual: usize,
170    },
171    /// A bounded dimension exceeds the declared upper bound.
172    #[error(
173        "tensor binding extent exceeds upper bound at axis {axis}: bound {bound}, got {actual}"
174    )]
175    UpperBoundExceeded {
176        /// Axis whose bound was exceeded.
177        axis: usize,
178        /// Declared upper bound.
179        bound: usize,
180        /// Bound tensor extent.
181        actual: usize,
182    },
183}
184
185/// Errors reported while atomically freezing semantic structure and bindings.
186#[derive(Debug, thiserror::Error)]
187#[non_exhaustive]
188pub enum ProgramFinishError {
189    /// One requested output belongs to another builder or names no value.
190    #[error("program output does not belong to this semantic-program builder")]
191    ForeignOutput,
192    /// Frozen structure failed an invariant check.
193    #[error("semantic-program structural validation failed: {source}")]
194    StructuralValidation {
195        /// Typed structural invariant failure.
196        #[source]
197        source: ProgramStructuralError,
198    },
199    /// A tensor default or large constant does not match its input declaration.
200    #[error("semantic-program binding finalization failed: {source}")]
201    BindingFinalization {
202        /// Typed binding mismatch.
203        #[source]
204        source: ProgramBindingError,
205    },
206}
207
208/// Failures produced by a validated semantic transform transaction.
209#[derive(Debug, thiserror::Error)]
210#[non_exhaustive]
211pub enum SemanticTransformError {
212    /// Program construction or import failed inside the transform.
213    #[error(transparent)]
214    Build(#[from] ProgramBuildError),
215    /// Atomic freeze failed after the transform returned roots.
216    #[error(transparent)]
217    Finish(#[from] ProgramFinishError),
218    /// The transform returned a value not owned by its destination builder.
219    #[error("semantic transform returned a foreign destination value")]
220    ForeignReturnedValue,
221    /// The transform did not carry every input tensor binding forward.
222    #[error("semantic transform discarded one or more tensor bindings")]
223    DroppedBindings,
224    /// The transform deliberately rejected this input.
225    #[error("semantic transform rejected the input")]
226    Rejected,
227}
228
229/// Invalid typed effect-resource identity.
230#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
231pub enum EffectResourceError {
232    /// Resource-family names must be nonempty and versioned.
233    #[error("effect resource family must be a nonempty versioned identifier")]
234    InvalidFamily,
235}