Skip to content

BE-71: HashQL: Consolidate AST special-form expansion stages into one#8870

Open
indietyp wants to merge 55 commits into
bm/be-481-hashql-lower-null-to-constantunit-during-reificationfrom
bm/be-71-hashql-consider-merging-ast-stages
Open

BE-71: HashQL: Consolidate AST special-form expansion stages into one#8870
indietyp wants to merge 55 commits into
bm/be-481-hashql-lower-null-to-constantunit-during-reificationfrom
bm/be-71-hashql-consider-merging-ast-stages

Conversation

@indietyp

@indietyp indietyp commented Jun 16, 2026

Copy link
Copy Markdown
Member

🌟 What is the purpose of this PR?

🏗️ This PR is large because it replaces three tightly coupled AST lowering passes with a single merged pass. Line breakdown: production code is +6295/-5451 (119 files); tests and snapshots are +2893/-2756 (692 files, mostly mechanical annotation updates due to changed diagnostic messages). The old passes (PreExpansionNameResolver, SpecialFormExpander, ImportResolver) share resolution state that the new Expander unifies, and the core module changes (universe-aware errors, KindSet, module depth, namespace .alias()) only exist to support the new pass. Splitting the core changes out would require backporting them to the old passes just to keep CI green before deleting those passes in the next PR. It is one logical change: merge three passes into one.

Replaces three AST lowering passes with a single Expander pass that resolves names, expands special forms, and resolves imports in one top-down traversal. This is the main deliverable of BE-71.

The old pipeline ran PreExpansionNameResolver, SpecialFormExpander, and ImportResolver sequentially, each walking the full AST. The new Expander does all three in a single walk, eliminating redundant traversals and making error recovery more coherent: diagnostics from nested expressions are no longer suppressed by early bail-outs in outer forms.

🔍 What does this change?

New Expander pass (hashql-ast/src/lower/expander/):

  • Single visitor that resolves paths, expands special forms (let, type, newtype, fn, use, as, if, input, index, access), and resolves imports
  • Each special form in its own file with a lower_* entry point
  • visit() method encapsulates save/restore/trampoline cycle, returns Option<CurrentItem>
  • CurrentItem { item, has_arguments } prevents aliasing of specialised references and guards intrinsic swallowing
  • Zero-allocation path rewriting via rotate_right/rotate_left + zip
  • Recovery over abort: invalid binding names use Ident::synthetic(sym::dummy) and continue collecting downstream diagnostics, returning Expr::dummy() only at the final gate
  • 39 diagnostic categories with per-variant constructors, S-expression syntax in messages, three-tier spelling suggestions, cross-universe hints ("exists as a type, not a value")

Module system changes (hashql-core):

  • KindSet bitfield (VALUE | TYPE | MODULE) for cross-universe error reporting
  • ItemNotFound and ImportNotFound enriched with expected: Option<Universe> and found: KindSet
  • Resolver scans for alternate-kind items when suggestions are enabled
  • resolve_relative produces ModuleRequired instead of ModuleNotFound when a non-module import with the same name exists
  • Module::depth as NonZero<u32> for ExactSizeIterator on absolute_path_rev
  • ModuleNamespace::alias() for identity-preserving rebinding

Removed:

  • PreExpansionNameResolver (~437 lines)
  • SpecialFormExpander (~1451 lines + ~1125 lines of diagnostics)
  • ImportResolver (~478 lines + ~712 lines of diagnostics)

Other:

  • lowering module renamed to lower
  • Compiletest suites rewired for the merged pass
  • Path truncation support for future re-exports (canonical path shorter than written path)

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

⚠️ Known issues

  • Path truncation for re-exports is implemented but untested: the intern_module debug assertion (item.module == containing_module) prevents constructing a re-export scenario in tests. Will be testable when re-export infrastructure lands.
  • Ambiguous, ModuleEmpty, and InvalidQueryLength resolution error paths are unreachable from the expander (single-universe resolution, no empty modules in stdlib, parser never produces empty paths). Diagnostic constructors exist for completeness but have no compiletest coverage.

🐾 Next steps

  • Diagnostic quality review pass
  • Re-export module infrastructure (would enable testing path truncation)

🛡 What tests cover this?

  • 557 compiletest UI tests, including 24 new tests for the expander:
    • Labeled argument rejection for all 9 special forms
    • Invalid binding names, invalid field access, invalid use paths
    • Intrinsic swallowing (let and type rebinding intrinsics)
    • Intrinsic type annotation errors
    • Generic arguments on intrinsics (both type and special form)
    • Cross-universe resolution ("cannot find value X" / "cannot find type X")
    • Duplicate generic constraints and duplicate use bindings
    • Package-not-found for nonexistent root packages
    • Multiple generic arguments on module path segments
  • All existing inherited compiletest tests from the old passes continue to pass under the new expander suite

❓ How to test this?

cargo run -p hashql-compiletest --all-features -- run

@github-actions

Copy link
Copy Markdown
Contributor

Benchmark results

@rust/hash-graph-benches – Integrations

policy_resolution_large

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2002 $$27.2 \mathrm{ms} \pm 222 \mathrm{μs}\left({\color{gray}-4.962 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.43 \mathrm{ms} \pm 21.4 \mathrm{μs}\left({\color{lightgreen}-5.775 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1001 $$12.3 \mathrm{ms} \pm 108 \mathrm{μs}\left({\color{lightgreen}-11.936 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 3314 $$43.3 \mathrm{ms} \pm 402 \mathrm{μs}\left({\color{lightgreen}-6.976 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$14.2 \mathrm{ms} \pm 122 \mathrm{μs}\left({\color{lightgreen}-14.259 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 1526 $$24.0 \mathrm{ms} \pm 211 \mathrm{μs}\left({\color{lightgreen}-8.311 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 2078 $$28.4 \mathrm{ms} \pm 225 \mathrm{μs}\left({\color{gray}-4.890 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.70 \mathrm{ms} \pm 22.3 \mathrm{μs}\left({\color{lightgreen}-7.845 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 1033 $$13.3 \mathrm{ms} \pm 112 \mathrm{μs}\left({\color{lightgreen}-11.684 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_medium

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 102 $$3.79 \mathrm{ms} \pm 25.8 \mathrm{μs}\left({\color{gray}-2.456 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.00 \mathrm{ms} \pm 17.8 \mathrm{μs}\left({\color{gray}-1.494 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 51 $$3.37 \mathrm{ms} \pm 25.6 \mathrm{μs}\left({\color{gray}-1.924 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 269 $$5.26 \mathrm{ms} \pm 44.4 \mathrm{μs}\left({\color{gray}-0.314 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.55 \mathrm{ms} \pm 22.5 \mathrm{μs}\left({\color{gray}0.325 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 107 $$4.18 \mathrm{ms} \pm 36.0 \mathrm{μs}\left({\color{gray}-0.178 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 133 $$4.43 \mathrm{ms} \pm 30.7 \mathrm{μs}\left({\color{gray}-1.900 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.47 \mathrm{ms} \pm 18.6 \mathrm{μs}\left({\color{gray}-3.075 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 63 $$4.19 \mathrm{ms} \pm 39.1 \mathrm{μs}\left({\color{gray}-1.283 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_none

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2 $$2.66 \mathrm{ms} \pm 12.2 \mathrm{μs}\left({\color{gray}-0.081 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.52 \mathrm{ms} \pm 16.9 \mathrm{μs}\left({\color{gray}-2.017 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1 $$2.67 \mathrm{ms} \pm 16.8 \mathrm{μs}\left({\color{gray}1.24 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 8 $$2.93 \mathrm{ms} \pm 17.7 \mathrm{μs}\left({\color{gray}0.268 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.74 \mathrm{ms} \pm 16.1 \mathrm{μs}\left({\color{gray}1.34 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 3 $$2.92 \mathrm{ms} \pm 19.8 \mathrm{μs}\left({\color{gray}0.423 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_small

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 52 $$3.02 \mathrm{ms} \pm 17.9 \mathrm{μs}\left({\color{gray}-3.446 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.73 \mathrm{ms} \pm 14.3 \mathrm{μs}\left({\color{gray}-3.175 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 25 $$2.96 \mathrm{ms} \pm 17.4 \mathrm{μs}\left({\color{gray}-3.901 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 94 $$3.49 \mathrm{ms} \pm 28.8 \mathrm{μs}\left({\color{gray}-2.134 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$2.95 \mathrm{ms} \pm 22.6 \mathrm{μs}\left({\color{gray}-2.208 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 26 $$3.31 \mathrm{ms} \pm 29.9 \mathrm{μs}\left({\color{gray}-1.871 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 66 $$3.37 \mathrm{ms} \pm 28.4 \mathrm{μs}\left({\color{gray}-1.760 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.93 \mathrm{ms} \pm 17.6 \mathrm{μs}\left({\color{gray}-3.258 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 29 $$3.39 \mathrm{ms} \pm 31.1 \mathrm{μs}\left({\color{gray}-1.662 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_complete

Function Value Mean Flame graphs
entity_by_id;one_depth 1 entities $$55.0 \mathrm{ms} \pm 411 \mathrm{μs}\left({\color{gray}-0.633 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 10 entities $$46.2 \mathrm{ms} \pm 246 \mathrm{μs}\left({\color{gray}-0.172 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 25 entities $$51.9 \mathrm{ms} \pm 346 \mathrm{μs}\left({\color{gray}0.491 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 5 entities $$44.4 \mathrm{ms} \pm 269 \mathrm{μs}\left({\color{gray}0.249 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 50 entities $$63.8 \mathrm{ms} \pm 421 \mathrm{μs}\left({\color{gray}1.65 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 1 entities $$62.5 \mathrm{ms} \pm 462 \mathrm{μs}\left({\color{gray}1.31 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 10 entities $$57.1 \mathrm{ms} \pm 427 \mathrm{μs}\left({\color{gray}1.47 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 25 entities $$104 \mathrm{ms} \pm 553 \mathrm{μs}\left({\color{red}5.81 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 5 entities $$56.9 \mathrm{ms} \pm 3.65 \mathrm{ms}\left({\color{red}22.3 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 50 entities $$299 \mathrm{ms} \pm 1.28 \mathrm{ms}\left({\color{lightgreen}-7.956 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 1 entities $$19.8 \mathrm{ms} \pm 135 \mathrm{μs}\left({\color{gray}2.30 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 10 entities $$20.1 \mathrm{ms} \pm 112 \mathrm{μs}\left({\color{gray}1.06 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 25 entities $$20.5 \mathrm{ms} \pm 131 \mathrm{μs}\left({\color{gray}0.914 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 5 entities $$19.6 \mathrm{ms} \pm 137 \mathrm{μs}\left({\color{gray}2.91 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 50 entities $$25.6 \mathrm{ms} \pm 172 \mathrm{μs}\left({\color{gray}0.323 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_linkless

Function Value Mean Flame graphs
entity_by_id 1 entities $$19.4 \mathrm{ms} \pm 123 \mathrm{μs}\left({\color{gray}2.78 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10 entities $$19.5 \mathrm{ms} \pm 108 \mathrm{μs}\left({\color{gray}1.90 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 100 entities $$20.1 \mathrm{ms} \pm 119 \mathrm{μs}\left({\color{gray}4.58 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 1000 entities $$21.3 \mathrm{ms} \pm 165 \mathrm{μs}\left({\color{red}5.79 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10000 entities $$27.4 \mathrm{ms} \pm 214 \mathrm{μs}\left({\color{gray}4.17 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity

Function Value Mean Flame graphs
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/block/v/1 $$34.8 \mathrm{ms} \pm 325 \mathrm{μs}\left({\color{gray}0.277 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1 $$35.7 \mathrm{ms} \pm 387 \mathrm{μs}\left({\color{gray}-0.183 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1 $$36.0 \mathrm{ms} \pm 326 \mathrm{μs}\left({\color{gray}2.14 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1 $$35.1 \mathrm{ms} \pm 293 \mathrm{μs}\left({\color{gray}3.30 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2 $$36.0 \mathrm{ms} \pm 308 \mathrm{μs}\left({\color{gray}4.04 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1 $$35.6 \mathrm{ms} \pm 334 \mathrm{μs}\left({\color{gray}2.78 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1 $$34.7 \mathrm{ms} \pm 374 \mathrm{μs}\left({\color{lightgreen}-6.464 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1 $$35.9 \mathrm{ms} \pm 296 \mathrm{μs}\left({\color{gray}2.65 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1 $$34.8 \mathrm{ms} \pm 393 \mathrm{μs}\left({\color{lightgreen}-5.946 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity_type

Function Value Mean Flame graphs
get_entity_type_by_id Account ID: bf5a9ef5-dc3b-43cf-a291-6210c0321eba $$8.69 \mathrm{ms} \pm 56.6 \mathrm{μs}\left({\color{gray}-2.601 \mathrm{\%}}\right) $$ Flame Graph

representative_read_multiple_entities

Function Value Mean Flame graphs
entity_by_property traversal_paths=0 0 $$96.1 \mathrm{ms} \pm 727 \mathrm{μs}\left({\color{lightgreen}-5.077 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$151 \mathrm{ms} \pm 695 \mathrm{μs}\left({\color{gray}-4.437 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$101 \mathrm{ms} \pm 524 \mathrm{μs}\left({\color{lightgreen}-7.327 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$113 \mathrm{ms} \pm 557 \mathrm{μs}\left({\color{lightgreen}-7.129 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$120 \mathrm{ms} \pm 935 \mathrm{μs}\left({\color{lightgreen}-6.040 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$131 \mathrm{ms} \pm 646 \mathrm{μs}\left({\color{gray}-4.509 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=0 0 $$105 \mathrm{ms} \pm 728 \mathrm{μs}\left({\color{gray}-4.056 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$135 \mathrm{ms} \pm 850 \mathrm{μs}\left({\color{lightgreen}-5.223 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$115 \mathrm{ms} \pm 658 \mathrm{μs}\left({\color{gray}-3.237 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$122 \mathrm{ms} \pm 755 \mathrm{μs}\left({\color{gray}-4.511 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$123 \mathrm{ms} \pm 694 \mathrm{μs}\left({\color{gray}-4.733 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$123 \mathrm{ms} \pm 751 \mathrm{μs}\left({\color{gray}-4.656 \mathrm{\%}}\right) $$

scenarios

Function Value Mean Flame graphs
full_test query-limited $$157 \mathrm{ms} \pm 2.65 \mathrm{ms}\left({\color{red}16.6 \mathrm{\%}}\right) $$ Flame Graph
full_test query-unlimited $$152 \mathrm{ms} \pm 819 \mathrm{μs}\left({\color{gray}3.28 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-limited $$42.7 \mathrm{ms} \pm 255 \mathrm{μs}\left({\color{gray}0.103 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-unlimited $$555 \mathrm{ms} \pm 1.61 \mathrm{ms}\left({\color{gray}0.783 \mathrm{\%}}\right) $$ Flame Graph

Comment thread libs/@local/hashql/ast/src/lower/expander/access.rs Outdated
Copilot AI review requested due to automatic review settings June 18, 2026 15:50
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 18, 2026 15:50 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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@indietyp indietyp force-pushed the bm/be-481-hashql-lower-null-to-constantunit-during-reification branch from f1a6855 to 942f634 Compare June 19, 2026 15:14
Copilot AI review requested due to automatic review settings June 19, 2026 15:14
@indietyp indietyp force-pushed the bm/be-71-hashql-consider-merging-ast-stages branch from 2b9c6dd to 0c15b58 Compare June 19, 2026 15:14

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0c15b58. Configure here.

Comment thread libs/@local/hashql/ast/src/lower/expander/mod.rs
Comment thread libs/@local/hashql/ast/src/lower/expander/type.rs

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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

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

Labels

area/deps Relates to third-party dependencies (area) area/infra Relates to version control, CI, CD or IaC (area) 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