Skip to content

BE-585, BE-591: HashQL: Add MIR interpreter test suite and refactor diagnostic categories#8837

Open
indietyp wants to merge 8 commits into
bm/be-583-hashql-diagnostics-docs-and-span-improvementsfrom
bm/be-585-hashql-split-mir-interpret-diagnostic-api
Open

BE-585, BE-591: HashQL: Add MIR interpreter test suite and refactor diagnostic categories#8837
indietyp wants to merge 8 commits into
bm/be-583-hashql-diagnostics-docs-and-span-improvementsfrom
bm/be-585-hashql-split-mir-interpret-diagnostic-api

Conversation

@indietyp

@indietyp indietyp commented Jun 8, 2026

Copy link
Copy Markdown
Member

🌟 What is the purpose of this PR?

This PR wires up the MIR interpreter so it can be exercised end-to-end through the compiletest suite, and restructures the diagnostic category hierarchy so that interpreter errors and bridge (PostgreSQL suspension) errors are unified under a single OrchestratorDiagnosticCategory type rather than being conflated under InterpretDiagnosticCategory.

Previously, bridge errors (query execution failures, row decoding, parameter encoding, etc.) were emitted as InterpretDiagnostic values with a Suspension subcategory bolted onto InterpretDiagnosticCategory. This made it impossible for downstream consumers to distinguish interpreter ICEs from orchestrator bridge failures. The new OrchestratorDiagnosticCategory enum has two variants — Interpret (forwarding interpreter errors) and Bridge (wrapping suspension failures) — giving callers a coherent, single diagnostic type from the orchestration layer.

On the interpreter side, RuntimeError::into_diagnostic is split into into_diagnostic (same category, InterpretDiagnosticCategory) and into_diagnostic_with (maps the category through a caller-supplied closure), enabling the orchestrator to embed interpreter diagnostics inside its own hierarchy without losing information.

A new mir/interpret compiletest suite is added that runs the full pipeline through the MIR interpreter and captures the output, with an initial test demonstrating that field projection through an opaque wrapper is not yet supported.

Additionally, StructBuilder::finish now accepts &InternSet<[Symbol]> directly instead of &Interner, Struct::new_unchecked is marked unsafe with documented safety requirements, all interpreter diagnostic severities are migrated from Severity::Bug/Severity::Error to Critical::BUG/Critical::ERROR, and comprehensive doc-examples are added across the interpreter value types (Dict, List, Struct, Tuple, Opaque, Ptr, Str, Num).

🔍 What does this change?

  • Introduces OrchestratorDiagnosticCategory with Interpret and Bridge variants, replacing the previous use of InterpretDiagnosticCategory::Suspension for bridge errors.
  • Adds BridgeDiagnosticCategory as the subcategory for suspension-fulfillment failures, replacing SuspensionDiagnosticCategory.
  • Removes SuspensionDiagnosticCategory and the Suspension variant from InterpretDiagnosticCategory.
  • Splits RuntimeError::into_diagnostic into into_diagnostic (identity category mapping) and into_diagnostic_with (caller-supplied category mapping), allowing the orchestrator to lift interpreter diagnostics into its own hierarchy.
  • Changes InterpretDiagnostic default severity kind from Severity to Critical, and migrates all diagnostic constructors from Severity::Bug/Severity::Error to Critical::BUG/Critical::ERROR.
  • Makes Struct::new_unchecked unsafe, documenting that callers must ensure fields are sorted; updates all call sites with unsafe blocks and safety comments.
  • Strengthens Struct::new to also reject unsorted field slices.
  • Changes StructBuilder::finish to accept &InternSet<'heap, [Symbol<'heap>]> instead of &Interner, narrowing the dependency.
  • Adds a mir/interpret compiletest suite that runs the interpreter and captures MIR as a secondary output.
  • Adds an initial interpreter test (access-struct-through-opaque) that documents the current limitation of projecting through opaque wrappers.
  • Exposes ReifyDiagnosticCategory, ReifyDiagnostic, and ReifyDiagnosticIssues publicly and adds MirDiagnosticCategory::Reify variant.
  • Adds Opaque::into_value, From<Symbol> for Str, and TryCloneIn for Str.
  • Adds #[inline] annotations and comprehensive doc-examples across interpreter value types.

🛡 What tests cover this?

  • New mir/interpret compiletest suite with access-struct-through-opaque as the first test case, covering the interpreter pipeline end-to-end.
  • Existing StructBuilder unit tests updated to use the new finish signature.
  • Existing interpreter unit tests updated for unsafe Struct::new_unchecked call sites.

❓ How to test this?

  1. Run the compiletest suite targeting mir/interpret.
  2. Confirm the access-struct-through-opaque test produces the expected stderr output showing the interpret::type-invariant diagnostic.
  3. Run the existing MIR interpreter unit tests to confirm no regressions.

indietyp added 5 commits June 8, 2026 11:58
chore: add new dependency

chore: format

feat: error module

feat: introduce hashql_eval interner

chore: checkpoint

feat: checkpoint

feat: checkpoint

chore: remove old value module

feat: checkpoint

feat: checkpoint

feat: checkpoint

feat: checkpoint

feat: checkpoint

chore: checkpoint

feat: move entity query into its own modul

fix: query request

feat: checkpoint (it compiles!)

feat: checkpoint

feat: checkpoint

feat: checkpoint

fix: issue around cached thunking

feat: covariance for opaque inners

fix: cfgattr serde

chore: remove graph module
Copilot AI review requested due to automatic review settings June 8, 2026 11:41
@cursor

cursor Bot commented Jun 8, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches eval orchestration error paths and public diagnostic types; behavior change is mainly clearer error taxonomy, but orchestrator run_in failure handling is on the critical query execution path.

Overview
Adds a mir/interpret compiletest suite that lowers to post-inline MIR, runs the standalone interpreter (suspensions stubbed with unimplemented!), and records MIR as a secondary artifact. The first UI case documents failing field projection through an opaque wrapper.

Orchestrator diagnostics are split from interpreter-only types: bridge failures use OrchestratorDiagnosticCategory (Interpret vs Bridge with BridgeDiagnosticCategory), replacing InterpretDiagnosticCategory::Suspension. Orchestrator::run_in returns OrchestratorDiagnostic and uses RuntimeError::into_diagnostic_with to nest interpreter categories under Interpret while bridge errors map via BridgeError::into_diagnostic.

On the MIR side, RuntimeError::into_diagnostic_with lifts categories for embedders; interpreter ICEs move from Severity to Critical::BUG / Critical::ERROR. Struct::new_unchecked is unsafe (sorted fields invariant); StructBuilder::finish takes &InternSet<[Symbol]> instead of &Interner (eval partial hydration and tests updated). MirDiagnosticCategory::Reify and public reify diagnostic exports are added; reify asserts struct field names are sorted.

Smaller API/doc work: Opaque::into_value, Str From<Symbol> / TryCloneIn, and doc examples on interpreter value types.

Reviewed by Cursor Bugbot for commit 5bd5e93. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions github-actions Bot added area/libs Relates to first-party libraries/crates/packages (area) type/eng > backend Owned by the @backend team area/tests New or updated tests labels Jun 8, 2026
@vercel

vercel Bot commented Jun 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hash Ready Ready Preview, Comment Jun 9, 2026 7:26am
petrinaut Ready Ready Preview Jun 9, 2026 7:26am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hashdotdesign-tokens Ignored Ignored Preview Jun 9, 2026 7:26am

@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.46429% with 87 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.56%. Comparing base (e6657ac) to head (5bd5e93).

Files with missing lines Patch % Lines
libs/@local/hashql/eval/src/orchestrator/error.rs 0.00% 56 Missing ⚠️
libs/@local/hashql/mir/src/interpret/error.rs 90.00% 10 Missing ⚠️
libs/@local/hashql/mir/src/interpret/value/str.rs 50.00% 10 Missing ⚠️
libs/@local/hashql/eval/src/orchestrator/mod.rs 33.33% 4 Missing ⚠️
...bs/@local/hashql/mir/src/interpret/value/struct.rs 96.82% 4 Missing ⚠️
...ibs/@local/hashql/eval/src/orchestrator/partial.rs 88.88% 1 Missing ⚠️
libs/@local/hashql/mir/src/error.rs 0.00% 1 Missing ⚠️
...ibs/@local/hashql/mir/src/interpret/value/tuple.rs 97.77% 1 Missing ⚠️
Additional details and impacted files
@@                                     Coverage Diff                                     @@
##           bm/be-583-hashql-diagnostics-docs-and-span-improvements    #8837      +/-   ##
===========================================================================================
+ Coverage                                                    59.23%   59.56%   +0.33%     
===========================================================================================
  Files                                                         1346     1347       +1     
  Lines                                                       130119   130913     +794     
  Branches                                                      5884     5884              
===========================================================================================
+ Hits                                                         77072    77982     +910     
+ Misses                                                       52142    52027     -115     
+ Partials                                                       905      904       -1     
Flag Coverage Δ
apps.hash-ai-worker-ts 1.39% <ø> (ø)
apps.hash-api 0.00% <ø> (ø)
local.hash-backend-utils 2.81% <ø> (ø)
local.hash-graph-sdk 9.63% <ø> (ø)
local.hash-isomorphic-utils 0.00% <ø> (ø)
rust.hash-graph-api 2.52% <ø> (ø)
rust.hashql-compiletest 28.24% <ø> (ø)
rust.hashql-eval 75.20% <14.08%> (-0.49%) ⬇️
rust.hashql-mir 88.45% <94.68%> (+1.39%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR wires the MIR interpreter into the compiletest harness for end-to-end execution tests, and refactors diagnostic category/severity plumbing so orchestration-layer (“bridge”) errors are no longer conflated with interpreter diagnostics. It also tightens/clarifies interpreter value invariants (notably struct field ordering), adds an initial mir/interpret UI test, and expands docs/examples across interpreter value types.

Changes:

  • Add a new mir/interpret compiletest suite that runs MIR through the interpreter and emits MIR as a secondary .mir output.
  • Introduce an orchestrator-level diagnostic category (OrchestratorDiagnosticCategory) that cleanly distinguishes interpreter errors from bridge (PostgreSQL suspension) failures.
  • Harden interpreter value APIs (e.g., Struct::new_unchecked becomes unsafe, Struct::new rejects unsorted fields; StructBuilder::finish takes &InternSet<[Symbol]>) and expand doc-examples/inline hints.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
libs/@local/hashql/mir/tests/ui/interpret/access-struct-through-opaque.stderr Expected stderr for the first MIR interpreter UI test.
libs/@local/hashql/mir/tests/ui/interpret/access-struct-through-opaque.jsonc New UI test case exercising interpreter end-to-end behavior.
libs/@local/hashql/mir/tests/ui/interpret/access-struct-through-opaque.aux.mir Secondary output snapshot of MIR for the UI test.
libs/@local/hashql/mir/tests/ui/interpret/.spec.toml Declares the new mir/interpret compiletest suite.
libs/@local/hashql/mir/src/reify/mod.rs Re-exports reify diagnostics publicly from the MIR crate.
libs/@local/hashql/mir/src/reify/error.rs Makes ReifyDiagnostic* type aliases public.
libs/@local/hashql/mir/src/interpret/value/tuple.rs Adds doc-examples and small API/inline tweaks for tuples.
libs/@local/hashql/mir/src/interpret/value/struct.rs Marks Struct::new_unchecked as unsafe, enforces sorted fields, refactors StructBuilder::finish signature, adds docs/examples.
libs/@local/hashql/mir/src/interpret/value/str.rs Adds From<Symbol> + TryCloneIn for Str and improves docs.
libs/@local/hashql/mir/src/interpret/value/ptr.rs Adds docs/examples and inline hints for function pointers.
libs/@local/hashql/mir/src/interpret/value/opaque.rs Adds Opaque::into_value and expands docs/examples.
libs/@local/hashql/mir/src/interpret/value/num.rs Expands docs/examples for total-order Num.
libs/@local/hashql/mir/src/interpret/value/mod.rs Adds/updates docs and examples for Value operations (type name, subscript, projection).
libs/@local/hashql/mir/src/interpret/value/list.rs Adds docs/examples for list behavior including negative indexing.
libs/@local/hashql/mir/src/interpret/value/dict.rs Adds docs/examples for ordered dict behavior.
libs/@local/hashql/mir/src/interpret/tests.rs Updates tests for unsafe struct construction and related safety comments.
libs/@local/hashql/mir/src/interpret/suspension/temporal.rs Small inline annotations for timestamp conversions.
libs/@local/hashql/mir/src/interpret/runtime.rs Minor inline change; runtime error-to-diagnostic wiring relies on updated severity/category APIs.
libs/@local/hashql/mir/src/interpret/locals.rs Updates struct construction call site for unsafe Struct::new_unchecked with safety justification.
libs/@local/hashql/mir/src/interpret/inputs.rs Adds inline on Default impl for inputs.
libs/@local/hashql/mir/src/interpret/error.rs Refactors interpreter diagnostics: removes suspension category from interpreter, switches default severity kind to Critical, adds category-lifting APIs.
libs/@local/hashql/mir/src/error.rs Adds a MIR diagnostic category variant for reify diagnostics.
libs/@local/hashql/eval/tests/orchestrator/execution.rs Adjusts error conversion for orchestrator diagnostics.
libs/@local/hashql/eval/src/orchestrator/partial.rs Updates call sites for StructBuilder::finish(&interner.symbols, ...).
libs/@local/hashql/eval/src/orchestrator/mod.rs Updates public API to return OrchestratorDiagnostic and uses category-lifting from interpreter errors.
libs/@local/hashql/eval/src/orchestrator/error.rs Introduces OrchestratorDiagnosticCategory with Interpret/Bridge variants and migrates bridge diagnostics to Critical.
libs/@local/hashql/compiletest/src/suite/mod.rs Registers the new mir/interpret suite.
libs/@local/hashql/compiletest/src/suite/mir_interpret.rs Implements the new mir/interpret suite runner.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread libs/@local/hashql/compiletest/src/suite/mir_interpret.rs
Comment thread libs/@local/hashql/mir/src/interpret/error.rs
Comment thread libs/@local/hashql/eval/src/orchestrator/error.rs
Comment thread libs/@local/hashql/eval/src/orchestrator/mod.rs
Comment thread libs/@local/hashql/mir/src/interpret/tests.rs
@codspeed-hq

codspeed-hq Bot commented Jun 8, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 24 untouched benchmarks
⏩ 56 skipped benchmarks1


Comparing bm/be-585-hashql-split-mir-interpret-diagnostic-api (5bd5e93) with bm/be-583-hashql-diagnostics-docs-and-span-improvements (e6657ac)

Open in CodSpeed

Footnotes

  1. 56 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@vercel vercel Bot temporarily deployed to Preview – petrinaut June 8, 2026 11:55 Inactive
Copilot AI review requested due to automatic review settings June 8, 2026 12:22
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 8, 2026 12:22 Inactive

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 1 comment.

Comment thread libs/@local/hashql/mir/src/interpret/locals.rs
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 8, 2026 13:05 Inactive
Copilot AI review requested due to automatic review settings June 9, 2026 07:17
@indietyp indietyp force-pushed the bm/be-583-hashql-diagnostics-docs-and-span-improvements branch from a58069f to e6657ac Compare June 9, 2026 07:17
@indietyp indietyp force-pushed the bm/be-585-hashql-split-mir-interpret-diagnostic-api branch from 9ab066d to 5bd5e93 Compare June 9, 2026 07:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 29 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/libs Relates to first-party libraries/crates/packages (area) area/tests New or updated tests type/eng > backend Owned by the @backend team

Development

Successfully merging this pull request may close these issues.

2 participants