Skip to content

Rust: std-typed receivers hijack same-named project methods, fabricating CALLS edges (37.6% of edges stdlib-shaped on 0.10.8) — minimal repro #2053

Description

@Nicolas0315

Version

0.10.8 (also reproduces on 0.9.0)

Platform

macOS (arm64), Darwin 25.6.0

Summary

On Rust, a method call whose receiver is a std type loses the receiver at extraction and exact-matches a same-named project method, fabricating a CALLS edge. PathBuf::join, Option::from, Vec::len etc. are attributed to project symbols that the calling file never mentions.

This is the Rust instance of the class already filed for Go (#1906, #1909, #1927) and cross-language (#1572). I did not find a Rust-specific issue open for it — #1694 (cfg-duplicated names) is closed and a different mechanism.

Minimal reproduction

Cargo.toml + a single src/lib.rs:

use std::path::{Path, PathBuf};

/// A project method named `join`. Only `real_caller` below calls it.
pub struct EvidenceTier(pub u8);
impl EvidenceTier {
    pub fn join(&self, other: &EvidenceTier) -> EvidenceTier {
        EvidenceTier(self.0.max(other.0))
    }
}

/// The ONLY legitimate caller of EvidenceTier::join.
pub fn real_caller() -> EvidenceTier {
    EvidenceTier(1).join(&EvidenceTier(2))
}

/// Calls std PathBuf::join. Must NOT produce an edge to EvidenceTier::join.
pub fn stdlib_receiver(root: &Path) -> PathBuf {
    root.join("subdir")
}

/// Call-expression receiver. Must NOT produce an edge to EvidenceTier::join.
pub fn call_expr_receiver(root: &Path) -> PathBuf {
    root.to_path_buf().join("nested")
}
codebase-memory-mcp cli index_repository --repo_path <repro>
codebase-memory-mcp cli query_graph --project <p> \
  --query "MATCH (a)-[:CALLS]->(b) RETURN a.name AS caller, b.name AS callee, b.qualified_name AS callee_qn"

Actual

  join               EvidenceTier  ...src.lib.EvidenceTier
  real_caller        join          ...src.lib.EvidenceTier.join     <- correct
  real_caller        EvidenceTier  ...src.lib.EvidenceTier
  stdlib_receiver    join          ...src.lib.EvidenceTier.join     <- FABRICATED
  call_expr_receiver join          ...src.lib.EvidenceTier.join     <- FABRICATED

Expected

EvidenceTier::join has exactly one caller (real_caller). stdlib_receiver and call_expr_receiver call std::path::Path::join / PathBuf::join, which is not a project symbol and should produce no CALLS edge to a project node.

Scale on a real repo

A 376k-line Rust workspace (860 .rs files, indexed as 53,989 nodes):

0.9.0 0.10.8
total CALLS edges 26,635 34,746
edges targeting stdlib-shaped names1 5,728 (21.5%) 13,065 (37.6%)

1 target name in new, len, join, iter, from, get, contains, push, take, ok, all, min, max, clone, into, next, insert, unwrap, to_string, … (70 names). Not every one of these is fabricated — some project methods legitimately carry those names — but spot-checks came back 100% fabricated:

  • scripts/reasoning-helper/src/path_safety.rs::accepts_child_pathEvidenceAxisTier::join.
    Real code is root.join("3.8.0"). grep -c EvidenceAxisTier in that file = 0.
  • plugins/grok-bench-v2/src/checkpoint.rs::absolutizeEvidenceAxisTier::join.
    Real code is fn absolutize(root: &Path, path: PathBuf) { root.join(path) }. Same file, EvidenceAxisTier count = 0.

Impact beyond the edges

get_architecture hotspots are ranked by this fabricated fan-in, so the "most important functions" list is wrong, not just noisy — on the repo above the top entries were join(426), matches(343), iter(257), len(234), i.e. std methods. That matches what #1572 reports for Louvain clusters.

Because the answer is confident, well-formed, and wrong, an agent that trusts trace_path for "who calls X" has no signal that it should fall back to grep. Suggestion: when the receiver type cannot be resolved, emit no edge (or a distinctly-typed low-confidence edge that trace_path filters by default) rather than name-matching into the project namespace — and exclude unresolved-receiver edges from hotspot/cluster ranking.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingparsing/qualityGraph extraction bugs, false positives, missing edgespriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions