vj-sim 0.1.0

Netlist, scheduler and process model of the vj SystemVerilog simulator.
Documentation
//! Elaboration error type (NL-008): every elaboration failure this crate
//! surfaces is a typed `ElabError`, never a panic and never a silently
//! swallowed construct — see the plan's "Global constraints" section on
//! exhaustive `sv_lang`/`sv_lang_kinds` kind matches.

/// An elaboration failure. `netlist::elaborate` never panics on malformed or
/// unsupported-but-syntactically-valid input; it returns one of these
/// instead.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ElabError {
    /// A construct this pass does not (yet) lower — e.g. a `checker`/
    /// primitive instantiation, a generate block, or any other symbol kind
    /// this DFS's member-kind match does not recognize as either "a child
    /// instance" or "a known-benign non-instantiating member". `hier_path`
    /// is `Symbol::hierarchical_path()` of the offending symbol; `detail`
    /// names the construct (its `SymbolKind`, `Debug`-formatted). Never a
    /// silent skip: a construct this pass cannot account for must never
    /// cause elaboration to quietly under-report the design's hierarchy
    /// (ARCHITECTURE §7 item 9).
    UnsupportedConstruct { hier_path: String, detail: String },
    /// A `sv_lang`/dataflow call itself returned an unexpected `None`/`Err`
    /// where this pass's own invariants say it should not have (e.g. an
    /// `Instance` symbol with no `instance_body()`).
    Frontend(String),
    /// Task 3 (NL-015): `confirm_and_assign_symbol_keys`'s defensive
    /// member-for-member re-check disagreed with
    /// `Symbol::instance_body_has_same_type`'s "same type" verdict for a
    /// group `merge_groups_within_bucket` already decided to merge. Never a
    /// panic and never a silently-corrupted merged `Template` — this is the
    /// hard-fail NL-015 requires. `member_index` is the position (in
    /// `members()` order) of the first disagreeing member.
    MergeInvariantViolated {
        canonical_hier_path: String,
        other_hier_path: String,
        member_index: usize,
        detail: String,
    },
}

impl std::fmt::Display for ElabError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            ElabError::UnsupportedConstruct { hier_path, detail } => {
                write!(
                    f,
                    "unsupported construct at `{hier_path}` ({detail}) — not lowered by this elaboration pass"
                )
            }
            ElabError::Frontend(msg) => write!(f, "sv-lang frontend error: {msg}"),
            ElabError::MergeInvariantViolated {
                canonical_hier_path,
                other_hier_path,
                member_index,
                detail,
            } => write!(
                f,
                "merge invariant violated between `{canonical_hier_path}` and \
                 `{other_hier_path}` at member {member_index}: {detail}"
            ),
        }
    }
}

impl std::error::Error for ElabError {}