Skip to main content

SexpWitness

Struct SexpWitness 

Source
pub struct SexpWitness {
    pub shape: SexpShape,
    pub display: String,
}
Expand description

Typed witness of an offending Sexp at a typed-entry rejection boundary — the joint identity (shape + literal) the substrate’s diagnostic surface owes the operator. Pairs the closed-set SexpShape projection (the twelve reachable Sexp outermost shapes the reader can produce) with the Sexp::Display projection (the literal value the operator wrote: 5, :foo, (list 1 2), notify-ref, etc.).

Mirror at the offending-value boundary of the prior-run SexpShape (typed-shape closed set), ExpectedKwargShape (expected-shape closed set), KwargPath (kwargs-path shapes), MacroDefHead (macro-definition-head closed set), UnquoteForm (template-marker syntactic forms), CompilerSpecIoStage (disk-persistence surface), and TemplateInvariantKind (bytecode-runtime surface) closed-set lifts: those enums key rejection variants on a typed identity carried inside the variant’s data shape; SexpWitness keys the OFFENDING-VALUE side (the got: String Sexp::Display slots on NonSymbolUnquoteTarget, SpliceOutsideList, NonSymbolParam, RestParamMissingName, DefmacroNonSymbolName, DefmacroNonListParams, MissingHeadSymbol, and any future variant taking a &Sexp at the helper boundary) on a typed joint identity so authoring tools (REPL, LSP, tatara-check) bind to BOTH witness.shape (the structural identity — pattern-matchable on SexpShape::List etc.) AND witness.display (the literal value — renderable verbatim) without losing either side.

Before this struct landed, the six error-builder helpers in macro_expand.rs (non_symbol_unquote_target, splice_outside_list, non_symbol_param, rest_param_missing_name, defmacro_non_symbol_name, defmacro_non_list_params) and one in domain.rs (missing_head_err’s caller) each projected &Sexp → String via Sexp::to_string() at the boundary — the structural SexpShape was lost. After this primitive lands, every offending- value variant slot that takes a SexpWitness carries the typed shape AND the literal jointly in ONE owned value the variant lives independent of the call frame on.

The byte-for-byte rendering contract is preserved: Display for SexpWitness writes only the display field, so a variant whose #[error(...)] annotation projects through {got} renders byte-identically to the legacy got: String shape — every downstream substring-grep consumer (tatara-check, REPL) passes unchanged. The gain is structural: tools that pattern-match on witness.shape == SexpShape::List now bind to the typed identity directly instead of substring-parsing the rendered literal.

Clone + Debug + PartialEq + Eq are retained (same posture as every other owned-data LispError field); Copy is dropped because the display: String is not Copy. When a future run gives Sexp source spans, pos: Option<usize> lands here in ONE place and every offending-value site picks up positional rendering with no per-variant edit — the same future-proofing posture KwargPath, SexpShape, and ExpectedKwargShape already carry.

Theory anchor: THEORY.md §V.1 — knowable platform; the offending- value’s joint identity (structural shape + renderable literal) becomes a TYPE rather than a String projection at the helper boundary that discards the shape. After this primitive lands the substrate’s understanding of “the offending Sexp at a typed-entry rejection” lives in ONE typed struct the diagnostic promotions hang off of. THEORY.md §VI.1 — generation over composition; seven inline got.to_string() projections at error-builder boundaries (six in macro_expand.rs, one in domain.rs::missing_head_err’s caller) is past the three-times-rule trigger. THEORY.md §II.1 invariant 1 — typed entry; the offending Sexp’s identity is part of the proof of WHAT the typed-entry gate rejected, and the typed witness makes both halves of that identity (shape + literal) load-bearing data on the variant rather than the literal-only String projection the legacy shape carried.

Fields§

§shape: SexpShape

Structural identity — the typed-shape projection (SexpShape::Int, SexpShape::List, etc.). Pattern-matchable; future pos: Option<usize> promotions land alongside this field once Sexp carries spans.

§display: String

Renderable identity — the Sexp::Display projection ("5", "(list 1 2)", ":foo", etc.). Owned so the witness lives independent of the call frame and crosses thread boundaries cleanly. Feeds the #[error(...)] annotation’s {got} slot via SexpWitness’s Display impl.

Implementations§

Source§

impl SexpWitness

Source

pub fn new(shape: SexpShape, display: impl Into<String>) -> Self

Owned constructor — pairs a typed SexpShape with an owned String projection of the offending Sexp::Display. Used by the sexp_witness(&Sexp) projection helper in domain.rs; hand-written TataraDomain impls that need to construct a witness at their own call boundary route through this constructor.

Trait Implementations§

Source§

impl Clone for SexpWitness

Source§

fn clone(&self) -> SexpWitness

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SexpWitness

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for SexpWitness

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for SexpWitness

Source§

impl PartialEq for SexpWitness

Source§

fn eq(&self, other: &SexpWitness) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for SexpWitness

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.