بنقرة واحدة
rmc-type-overlaps
Rust name collisions and module shadows.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Rust name collisions and module shadows.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Preview a Rust symbol rename — exact reference set & refactor probe.
Audit a Rust crate's public API.
Enforce Rust crate-edge rules.
Audit Rust attributes and doc-comments.
Rust fn-level call graphs.
Task-conditioned workspace subgraph — nodes, edges, hierarchy.
| name | rmc-type-overlaps |
| description | Rust name collisions and module shadows. |
| argument-hint | [crate-name] [workspace-path] |
| allowed-tools | Read, mcp__rust-code-mcp__* |
Audit a Rust workspace for name collisions and namespace footguns: same type name in multiple crates, modules shadowing workspace crates, within-crate duplicate type names, and common fn names hinting at missing abstractions.
Two scopes:
The workflow distinguishes intentional design (wire vs domain types, etc.) from accidental migration debt or footguns.
For semantic-similarity duplicates (same body, different name), use
rmc-semantic-overlaps. For half-finished migration detection in depth,
use rmc-refactor-plan (Recipe 13).
build_hypergraph(directory=<absolute-path>)
If the schema bumped or sources changed, this rebuilds. Otherwise reuse is sub-second.
overlaps(directory=...)
Returns four buckets:
cross_crate_type_collisions — same type name in 2+ cratesmodule_shadows — mod X matching a workspace crate namewithin_crate_type_duplicates — same name in different submodules of one cratecommon_fn_names — fn names appearing in 4+ cratesFor each entry, fetch usage on both qualified names in parallel:
who_uses_summary(directory=..., target=A_qualified_name)
who_uses_summary(directory=..., target=B_qualified_name)
Apply this decision matrix:
| Pattern | Verdict | Severity |
|---|---|---|
| Both used by the same consumer module | Likely accidental dupe or half-finished migration. The consumer is converting between them. | 🔴 High |
| Different consumer sets, no overlap | Independent concepts with shared name. Functional but ambiguous. | 🟢 Low |
| Different shapes (Struct vs Enum, fields differ) | Definitely independent. Pure naming collision. | 🟢 Low |
| One side is a re-export alias for the other | Verify it's intentional; if just legacy, drop the alias. | 🟡 Medium |
| Both sides have non-trivial unique consumers + same domain area | Genuine ambiguity — domain split (wire/domain types) or candidate for unification. | 🟡 Medium |
To dig deeper:
find_definition(symbol_name=A_unqualified_name) → file:line for each definition
read_file_content(file_path=...) → inspect actual struct/enum bodies
get_similar_code(query=<one-of-the-bodies>) → semantic neighbors (catches dupes overlaps misses)
For each shadow (crate=X, shadowed=Y):
Filter crate_edges for consumer_crate=X, producer_crate=Y:
Y::... resolve to the local mod Y not the workspace crate Y.
Verify call sites with read_file_content.use Y::... inside X gets the local module silently.Both warrant renaming the local module.
Most within-crate duplicates are test fixtures replicated across test modules. Pattern recognition:
Mock*, Fake*, Stub*, Test*, Recording* →
test-fixture duplicates.tests, test, fixtures, common →
almost certainly fixtures.For test fixtures:
<crate>::tests::common::* module.For non-fixture within-crate duplicates:
read_file_content(file_path=...) → inspect each definition
get_similar_code(query=<body>) → confirm semantic equivalence
Decide: merge to single canonical home (if equivalent), or document the intentional split.
common_fn_names of main is expected (one per binary). Other entries
warrant checking:
init, default, new, apply in 4+ crates → probably normal Rust
idioms, not actionable.parse_config, a Config trait might
be earned.🔴 High — Same-name type used by the same consumer (migration debt)
🔴 High — Module shadow + actual workspace-crate dep (real bug risk)
🟡 Medium — Different-shape collisions in same domain area (structural ambiguity)
🟡 Medium — Module shadow without dep (footgun)
🟢 Low — Independent concepts with shared name (rename for clarity)
🟢 Low — Test-fixture duplicates (mechanical refactor)
⚪ Info — common_fn_names that confirm idiomatic Rust (no action)
overlaps(directory=...) → workspace-wide overlap data
module_tree(directory=..., krate=X) → full crate structure
The overlaps call returns workspace data; filter relevant entries to
those involving crate X.
From cross_crate_type_collisions: keep entries where any location has
crate_name=X.
From module_shadows: keep if crate_name=X (X is the shadowing crate)
OR shadowed_crate=X (X is the shadowed crate).
From within_crate_type_duplicates: keep if crate_name=X.
For each filtered collision, run who_uses_summary on both qualified
names. Apply the same decision matrix as Scope 1 Step 2.
Apply the same fixtures-vs-real-dupes pattern as Scope 1 Step 4. For X specifically:
module_tree(X) looking at the parent paths of each duplicate.tests, unit, common modules →
mechanical refactor.Walk module_tree(X) looking for:
unit or test containing
a *Display or *Presentation type.pub fn at depth 5 might be a leak.tests at one level, unit at another,
common at a third.For each pair of types within module_tree(X) with the same display_name:
within_crate_type_duplicates, that's already caught.module_tree's kind field disambiguates (Item.Method vs
Item.Struct).For types with many methods, scan for inconsistent naming:
new? Some from? Some create?from_io, from_parse, etc., consistent?module_tree shows methods as children of types. Inconsistent patterns
are subjective but worth noting.
| Finding | Action |
|---|---|
| Type collision with same-consumer migration debt involving X | Pick canonical home, delete duplicate (HIGH severity) |
| Module in X shadows a workspace crate | Rename the local module (MEDIUM-HIGH depending on if dep also exists) |
| Test fixtures duplicated in X | Factor into X::tests::common::* |
| Production duplicates in X | Read-and-merge or document split |
| Naming-only collision (different shapes) | Rename for clarity (LOW) |
| Namespace overload (test + prod in same module) | Split modules |
| If you see... | Probably... |
|---|---|
| Same name in domain + provider crates | Wire/domain split (intentional) |
| Same name in core + tests modules | Test fixture duplicate (mechanical refactor) |
| Same name in 5+ test modules of one crate | Recurring test fixture (factor to common) |
| Module name shadowing crate + dep edge to that crate | Real bug |
| Module name shadowing crate, no dep | Footgun (rename anyway) |
| Two types with same name, different shapes (Struct vs Enum) | Independent concepts (rename for clarity) |
| Two types with same name + same consumer module | Migration debt (HIGH) |
Common fn name main in many crates | Expected (binaries) |
Common fn name init, default, new | Idiomatic Rust (no action) |
| Other common fn name in 4+ crates | Possible missing trait abstraction |
coding-agent-bad5 cross-crate collisions, 1 module shadow, 6 within-crate duplicates. Top
severity: AgentConfig exists in both agent::config and config crates,
both used by coding-agent::compose — half-finished migration. Plus
agent::config shadows the workspace config crate (footgun). 4 of the
6 within-crate duplicates are test mocks (MockProvider, MockRegistry,
MockSessionStore, MockTool). Common fn names: empty (good hygiene
signal).
tui in coding-agent-bad1 within-crate duplicate (TestEventSender in tui::unit::bridge_plugin
and tui::unit::replay, test fixtures), 1 cross-crate collision
(ToolName — Enum in tui vs Struct in permissions, different shapes,
low-severity rename), 1 namespace overload (tui::unit mixes test
fixtures with tui::unit::presentation::ToolName which is production
code). Total cleanup: factor TestEventSender, rename ToolName, split unit
module. Few hours of work.
overlaps is name-equality / structure-only. For content-similar dupes
(same body, different name), use rmc-semantic-overlaps.common_fn_names threshold is 4 crates. Customizing the threshold is
not exposed.module_tree siblings but are not
flagged as duplicates by overlaps.overlaps if their definition
site is opaque to the HIR.