원클릭으로
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.