Skip to content

Silent BytecodeTypeId(0) fallback in type resolution swallows a must-hold invariant #474

Description

@zharinov

Problem

Type resolution silently falls back to BytecodeTypeId(0) instead of failing loudly. This breaks the project's invariant discipline: a swallowed must-hold fact should be made loud.

After a successful analyze, every referenced type must resolve. A miss is our bug. It should panic, not silently alias to T0 and emit a wrong-typed table.

  • emit/type_table.rs:127 uses .unwrap_or(BytecodeTypeId(0)) when collecting a TypeName's id.
  • emit/type_table.rs:271-272 resolve_type returns Ok(BytecodeTypeId(0)) with a "should not happen for well-formed types" comment.

Both spots are inside the trust boundary (post-analyze). CLAUDE.md's "Invariant Discipline" says state invariants loudly here (panic!/.expect()/invariants.rs), not swallow them with unwrap_or/.ok().

Cause

emit/type_table.rs:127 and emit/type_table.rs:271-272 both turn an unresolved-type miss into a T0 value instead of a loud failure.

Fix

Replace both silent T0 fallbacks with a loud failure (.expect(...) / panic! / an invariants.rs ensure_*) that names the unresolved type.

The fallback was never meant to fire for well-formed queries:

  • Valid input behaves the same.
  • A silent miscompile becomes a caught bug.

Acceptance

  • Resolving an unresolvable type panics with a descriptive message in debug/test builds instead of emitting T0.
  • No behavioral change for well-formed queries.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions