Skip to main content

tensorlogic_compiler/error_recovery/
mod.rs

1//! Partial error recovery for multi-expression compilation.
2//!
3//! TensorLogic historically supported a single **strict** compilation mode:
4//! [`crate::compile_to_einsum`] returns the first error it encounters and
5//! aborts the whole compile. For real programs that carry several rules or
6//! expressions this is overly brittle — a single bad rule prevents useful
7//! feedback about the rest of the program.
8//!
9//! This module introduces a complementary **tolerant** mode. In tolerant
10//! mode the compiler treats the input as a *program* (slice of
11//! [`tensorlogic_ir::TLExpr`]), compiles each expression in isolation, and
12//! collects per-expression diagnostics into a
13//! [`DiagnosticCollector`]. Non-fatal problems in one expression never
14//! prevent siblings from compiling.
15//!
16//! # Quick start
17//!
18//! ```
19//! use tensorlogic_compiler::error_recovery::{
20//!     compile_tolerant, RecoveryStrategy, Severity,
21//! };
22//! use tensorlogic_ir::{TLExpr, Term};
23//!
24//! let program = vec![
25//!     TLExpr::pred("p", vec![Term::var("x")]),
26//!     TLExpr::pred("q", vec![Term::var("y")]),
27//! ];
28//! let result = compile_tolerant(&program);
29//! assert_eq!(result.graphs.len(), 2);
30//! assert!(result.is_all_success());
31//! assert!(result.diagnostics.is_empty());
32//! # let _ = RecoveryStrategy::SkipOnError;
33//! # let _ = Severity::Error;
34//! ```
35//!
36//! # Design
37//!
38//! * **Scope**: recovery happens at the *compile-one-expression boundary*.
39//!   Each expression's own compilation path keeps propagating `Result::Err`
40//!   internally; the tolerant driver merely intercepts that `Err` (and any
41//!   panic, via [`std::panic::catch_unwind`]) and converts it into a
42//!   [`Diagnostic`]. No `catch_unwind` is sprinkled into inner passes.
43//! * **Strict mode is untouched**: [`crate::compile_to_einsum`] and
44//!   [`crate::compile_to_einsum_with_context`] retain their pre-existing
45//!   behaviour. The tolerant driver is a *new* public entry point.
46//! * **Configurable policy**: [`RecoveryStrategy`] selects one of
47//!   `SkipOnError`, `SkipOnFatal`, `AbortOnAny` — see its docs for the
48//!   full decision table.
49//!
50//! # Re-exports
51//!
52//! The commonly used types are re-exported at the module root so downstream
53//! callers can `use tensorlogic_compiler::error_recovery::*`.
54
55mod collector;
56mod diagnostic;
57mod strategy;
58mod tolerant_compiler;
59
60#[cfg(test)]
61mod tests;
62
63pub use collector::DiagnosticCollector;
64pub use diagnostic::{Diagnostic, Severity, SourceSpan};
65pub use strategy::{RecoveryAction, RecoveryStrategy};
66pub use tolerant_compiler::{
67    compile_tolerant, compile_tolerant_with_strategy, PartialCompilationResult, TolerantCompiler,
68};