1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! Public, backend-agnostic surface for Relon evaluation.
//!
//! This crate is the seam between hosts and evaluator backends; it only
//! re-exports the types a caller actually sees:
//!
//! * Data shapes: [`Value`], [`Scope`], [`Thunk`], [`RuntimeError`].
//! * Host configuration surface: [`Context`], [`Capabilities`],
//! [`NativeFnGate`], native-fn / decorator registration.
//! * Policy boundary: the [`CapabilityGate`] trait — single source of
//! capability-policy truth consulted by every backend (see
//! `capability` module docs for the enforcement-timing diff
//! between dispatch-time tree-walker checks and vtable-build-time
//! cranelift checks).
//! * Backend contract: the [`Evaluator`] trait — five `&self` methods
//! covering one full evaluation lifecycle.
//!
//! A backend (tree-walking `relon_evaluator::TreeWalkEvaluator`,
//! cranelift AOT, LLVM AOT, wasm host wrapper, ...) implements this
//! single trait; hosts then hold a `Box<dyn Evaluator>` for dynamic
//! dispatch / backend swap.
//!
//! Trait object-safety is a hard requirement: every method is `&self` plus
//! concrete in/out types — no generic methods.
// `unsafe_code` is forbidden everywhere except the SSO `SmolStr` module,
// which needs a single `str::from_utf8_unchecked` on the inline-payload
// borrow to keep `as_str()` cost on par with `String::as_str()`. The
// invariant is local — every constructor fills `data[..len]` from a
// `&str` / `String` so the bytes are UTF-8 by construction — and the
// `unsafe` block has an explicit `// SAFETY:` comment documenting it.
// rustc ≥ 1.93 false-positive: `unused_assignments` fires on fields of every
// `#[derive(miette::Diagnostic)]` / `thiserror::Error` enum (the derive
// expands to internal let-bindings that the lint mis-reads). Mirror the
// evaluator crate's allow and drop it once the rustc fix lands.
pub use CapabilityGate;
pub use ;
pub use ;
pub use RuntimeError;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
use HashMap;
use Arc;
/// Backend-agnostic evaluator contract.
///
/// Implementations turn an analyzed AST into a [`Value`]. The interface is
/// deliberately object-safe: every method is `&self` with concrete-type
/// arguments and return values — no generic methods — so hosts can hold a
/// `Box<dyn Evaluator>` for backend swap or dynamic dispatch.
///
/// The five methods cover one full evaluation lifecycle:
///
/// * [`eval`](Self::eval) — evaluate a single node (fragment / debug entry).
/// * [`eval_root`](Self::eval_root) — evaluate the document attached via
/// `Context::with_root` as a library / static config.
/// * [`run_main`](Self::run_main) — evaluate the document as an entry
/// program: check host `args` against the `#main(...)` signature, bind
/// them, then walk the body.
/// * [`force_thunk`](Self::force_thunk) — drive a lazy dict entry to a
/// value, caching the result for later accesses.
/// * [`invoke_closure`](Self::invoke_closure) — call a constructed closure
/// value with positional args; the shortest entry point for hosts that
/// treat Relon closures as plain callbacks.