Skip to content

fix(dead-code): resolve cross-crate method calls + skip public API by default - #529

Merged
ajianaz merged 2 commits into
developfrom
fix/519-deadcode-cross-crate-calls
Aug 27, 2026
Merged

fix(dead-code): resolve cross-crate method calls + skip public API by default#529
ajianaz merged 2 commits into
developfrom
fix/519-deadcode-cross-crate-calls

Conversation

@ajianaz

@ajianaz ajianaz commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Fixes #519
Fixes #520

Stacked pair (both target the dead-code usability problem on the uteke workspace, so they share a branch; #520 builds directly on top of #519's edge resolution).

What

#519 — cross-crate method calls not resolved (557 FPs)

  • Method calls inside Rust impl blocks were never walked for call edges (only top-level free functions were)
  • Call targets stored raw AST text (self.export_full, std::mem::drop) which can never join against bare symbol names
  • Fix: impl-block function bodies get extract_calls_from_node; new normalize_callee_name reduces targets to the final name segment. Applies to every language routed through the shared tree-sitter walker

#520 — pub API surface counted as dead code

  • find_dead_code skips pub (incl. pub(crate)) and export items by default, keyed off captured signatures
  • New --include-pub CLI flag and include_pub_api MCP parameter opt back in
  • cora dead-code now resolves the project root exactly like cora index

Why

Dead-code detection produced unusable output on real workspaces: 557 false positives from unresolved cross-crate method calls, plus public API surface counted as dead code.

Testing

  • Regression tests: bare-name edge extraction (AST level), two-file cross-crate dead-code integration mirroring the uteke case, pub-skip default/opt-in/private-helper
  • On cora-code itself: 213 findings drop to 89 with the default filter
  • Full suite green (897); fmt clean; zero new clippy findings vs develop

All commits signed-off (DCO).

…sitives

Method calls inside Rust impl blocks were never walked for call edges
(only top-level free functions were), and method/qualified call targets
stored the raw AST text ('self.export_full', 'std::mem::drop') which can
never join against bare symbol names. Both made find_dead_code flag
symbols that are called across files/crates — 557 false positives on a
5-crate workspace (#519).

- impl-block function bodies now get extract_calls_from_node like free
  functions, recording their internal calls
- new normalize_callee_name reduces targets to the final name segment,
  so self.x(), manager.y() and std::mem::drop() all land on x/y/drop
- applies to every language routed through the shared walker

Regression tests: bare-name edge extraction (AST level) and a two-file
cross-crate dead-code integration mirroring the uteke case.

Signed-off-by: ajianaz <ajianaz@users.noreply.github.com>
Majority of dead-code noise on library workspaces is pub API meant for
external consumption — 557 findings on uteke were mostly pub fns in
lib crates (#520). Missing internal callers does not make them dead.

- find_dead_code skips pub (incl. pub(crate)) and export items by
  default, keyed off captured signatures; DeadCodeOptions.include_pub_api
  opts back in
- new --include-pub CLI flag and include_pub_api MCP parameter
- cora dead-code now resolves the project root exactly like cora index,
  so queries hit the same workspace project after #522

On cora-code itself: 213 findings drop to 89 with the default filter.
Regression test covers pub-skip default, opt-in flag, private helper.

Signed-off-by: ajianaz <ajianaz@users.noreply.github.com>
@ajianaz
ajianaz merged commit f8c1242 into develop Aug 27, 2026
17 of 18 checks passed
@ajianaz
ajianaz deleted the fix/519-deadcode-cross-crate-calls branch August 27, 2026 12:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant