vj_sim/netlist/error.rs
1//! Elaboration error type (NL-008): every elaboration failure this crate
2//! surfaces is a typed `ElabError`, never a panic and never a silently
3//! swallowed construct — see the plan's "Global constraints" section on
4//! exhaustive `sv_lang`/`sv_lang_kinds` kind matches.
5
6/// An elaboration failure. `netlist::elaborate` never panics on malformed or
7/// unsupported-but-syntactically-valid input; it returns one of these
8/// instead.
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum ElabError {
11 /// A construct this pass does not (yet) lower — e.g. a `checker`/
12 /// primitive instantiation, a generate block, or any other symbol kind
13 /// this DFS's member-kind match does not recognize as either "a child
14 /// instance" or "a known-benign non-instantiating member". `hier_path`
15 /// is `Symbol::hierarchical_path()` of the offending symbol; `detail`
16 /// names the construct (its `SymbolKind`, `Debug`-formatted). Never a
17 /// silent skip: a construct this pass cannot account for must never
18 /// cause elaboration to quietly under-report the design's hierarchy
19 /// (ARCHITECTURE §7 item 9).
20 UnsupportedConstruct { hier_path: String, detail: String },
21 /// A `sv_lang`/dataflow call itself returned an unexpected `None`/`Err`
22 /// where this pass's own invariants say it should not have (e.g. an
23 /// `Instance` symbol with no `instance_body()`).
24 Frontend(String),
25 /// Task 3 (NL-015): `confirm_and_assign_symbol_keys`'s defensive
26 /// member-for-member re-check disagreed with
27 /// `Symbol::instance_body_has_same_type`'s "same type" verdict for a
28 /// group `merge_groups_within_bucket` already decided to merge. Never a
29 /// panic and never a silently-corrupted merged `Template` — this is the
30 /// hard-fail NL-015 requires. `member_index` is the position (in
31 /// `members()` order) of the first disagreeing member.
32 MergeInvariantViolated {
33 canonical_hier_path: String,
34 other_hier_path: String,
35 member_index: usize,
36 detail: String,
37 },
38}
39
40impl std::fmt::Display for ElabError {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 match self {
43 ElabError::UnsupportedConstruct { hier_path, detail } => {
44 write!(
45 f,
46 "unsupported construct at `{hier_path}` ({detail}) — not lowered by this elaboration pass"
47 )
48 }
49 ElabError::Frontend(msg) => write!(f, "sv-lang frontend error: {msg}"),
50 ElabError::MergeInvariantViolated {
51 canonical_hier_path,
52 other_hier_path,
53 member_index,
54 detail,
55 } => write!(
56 f,
57 "merge invariant violated between `{canonical_hier_path}` and \
58 `{other_hier_path}` at member {member_index}: {detail}"
59 ),
60 }
61 }
62}
63
64impl std::error::Error for ElabError {}