Skip to content

fix(ingestion): dedupe Rust mod items per #[path] value - #2943

Open
Pushpak731 wants to merge 2 commits into
repowise-dev:mainfrom
Pushpak731:fix/rust-mod-path-dedup
Open

Pushpak731 wants to merge 2 commits into
repowise-dev:mainfrom
Pushpak731:fix/rust-mod-path-dedup

Conversation

@Pushpak731

Copy link
Copy Markdown

Summary

  • The raw-statement dedup key for a Rust mod_item is now qualified with its #[path] attribute value: mod imp; has the same raw text under two #[cfg] gates, but with different #[path] targets it is a feature-flag twin, not a duplicate. The file named by the second declaration previously lost its import edge and was then reported as unreachable with its exports unused (the ripgrep crates/core/index/mod.rs shape from the issue).
  • True duplicates (same raw text and same path, or no path at all) still dedupe; use statements and all other languages are untouched. Implementation follows the issue's suggestion of a Rust-specific key, like the existing Pascal/Elixir/F# pre-dedup precedent.

Related Issues

Closes #2935

Test Plan

  • Tests pass (pytest)
  • Lint passes (ruff check .)

New tests/unit/ingestion/test_rust_mod_path_dedup.py (30 tests): parser-level dedup semantics (the ripgrep and platform-twin shapes, same-path and no-path dedup guards, attribute order, doc comments, visibility modifiers, three-way gates, subdirectory paths, nearest-of-two path attributes, mixed use/mod) and end-to-end graph/dead-code assertions (both twin files get importer edges, neither is flagged unreachable/unused-export, no double edges for real duplicates, plain mod default-layout resolution unchanged). Full tests/unit/ingestion/: 4125 passed, 5 skipped, 2 xfailed; ruff check clean.

Checklist

  • My code follows the project's code style
  • I have added tests for new functionality
  • All existing tests still pass
  • I have updated documentation if needed

… loop

A defer immediately followed by a return, or by a break that exits the
for loop (not a switch/select case, and not only an inner loop of a
nest), is reached at most once per entry, so the deferred call cannot
pile up per iteration. Unlabeled break resolution walks to the innermost
breakable statement; a labeled break counts only when the label names a
for statement with no further loop above it up to the function scope.
Everything else - a call between the defer and the exit, continue,
switch/select-case breaks, labels naming inner statements, nested-loop
breaks - keeps firing, and the existing fixture count is unchanged.

Closes repowise-dev#2938
A mod_item's raw text excludes its outer attributes, so two
#[cfg]-gated 'mod imp;' declarations targeting different #[path] files
collide in the raw-statement dedup and the second file loses its import
edge - and is then reported as unreachable with its exports unused
(the ripgrep index/mod.rs shape). Qualify the dedup key with the
#[path] value for mod items; true duplicates (same raw text, same or
no path) still dedupe.

Closes repowise-dev#2935
Copilot AI balanced review requested due to automatic review settings October 2, 2026 13:39

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 was unable to review this pull request because the user who requested the review has reached their quota limit.

@repowise-bot

repowise-bot Bot commented Oct 2, 2026

Copy link
Copy Markdown

🔍 1 thing to check

  1. 4 files that usually change with this PR's files are not in it: packages/core/src/repowise/core/ingestion/models.py, packages/core/src/repowise/core/analysis/dead_code/analyzer.py, packages/core/src/repowise/core/ingestion/call_resolver.py (+1 more)

✅ Health of changed files: 2.3 → 3.9 (+1.6)

👀 Suggested reviewers @RaghavChamadiya


📊 See the full report for this PR
Blast radius, every caller of the contracts it changes, and health before and after. No sign-in.
Plain markdown for agents

Settings and updates

Updated 2026-10-02 13:39 UTC
Silence one PR with [skip repowise] in the title · Bot settings
⭐ Star Repowise · 📥 Install on another repo

@repowise-bot

repowise-bot Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Repowise checks

Check Result
Coverage Waiting for this PR's CI to upload a report (last report from this repo 27 minutes ago)
Tests 1 of 2 changed files reached by a test (inferred) · 1 reached by no test
Security No new findings on changed lines
Doc drift No drift in docs this PR edits · 1 document name changed files
Tests: which tests reach the changed files (inferred)
  • packages/core/src/repowise/core/analysis/health/perf/dialects/go.py: No test reaches this file (inferred)
  • packages/core/src/repowise/core/ingestion/parser.py: tests/unit/ingestion/parser/test_query_compilation.py, tests/unit/ingestion/parser/test_vbnet.py and 244 more (call graph)

Inferred from the code graph of the last indexed commit (a684707), nearest tests first; a test reaching a file does not mean it covers the changed lines.

Doc drift
  • docs/reference/COMPUTED_GLOSSARY.md names packages/core/src/repowise/core/ingestion/parser.py and is not in this PR

Configure checks: bot settings

@RaghavChamadiya

Copy link
Copy Markdown
Member

Thanks @Pushpak731, qualifying the dedup key with the #[path] value is the right shape for #2935, and the ripgrep twin-module case plus the same-path guard in your tests cover it well.

One thing before I can merge: this branch carries a second commit, the Go defer_in_loop change that is also open as #2942. Squash-merging would land both changes under this PR. Could you rebase so only the fix(ingestion): dedupe Rust mod items per #[path] value commit remains (git rebase -i origin/main, drop the Go commit, git push --force-with-lease)? Nothing else needs to change. Ping me once it is pushed and I will merge.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A Rust file selected by a second #[path] mod with the same name is reported as unreachable

3 participants