fix(rust): wrap modules in mod name { ... } instead of inlining (#1)#3
Merged
Merged
Conversation
Module flattening previously inlined each module's body into a single
shared namespace and then stripped module qualifiers with a regex. Any
project where two modules defined an item with the same name (e.g.
`helper`) failed to compile with E0428 once the bodies collided.
Flatten by wrapping instead: every `mod name;` declaration is expanded
recursively into an inline `mod name { <body> }` block. Each module keeps
its own namespace, so:
- same-named items across modules no longer collide;
- qualified paths (`crate::a::b`, `mod::fn()`) keep resolving, so the
separate qualifier-stripping step is gone;
- `use` statements (including globs) are preserved rather than removed;
- `//!` module docs stay valid as the first item inside the block.
This mirrors cargo-equip's approach and lets prepkit handle library-style
multi-module projects, not just flat single-namespace ones. The dependency
graph / topological sort is dropped: Rust resolves items crate-wide
regardless of order, so wrapped modules need no reordering.
Adds the name-collision reproduction as a fixture + regression test
(incl. an rustc compile check) and updates snapshots and the README.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1.
Problem
prepkit rust preprocessflattened modules by inlining each module's body into a single shared namespace and then strippingmod::qualifiers with a regex. Any project where two modules defined an item with the same name collided once inlined:Fix
Flatten by wrapping instead: every
mod name;declaration is recursively expanded into an inlinemod name { <body> }block. Each module keeps its own namespace, so:crate::a::b,module::fn()) keep resolving — the separate qualifier-stripping step is gone (see rust preprocess: module-qualifier stripping removes valid path segments (std sub-modules,Type::method) #2);usestatements (including globs) are preserved rather than removed;//!module-level docs stay valid as the first item inside the block.This mirrors
cargo-equip's approach and lets prepkit handle library-style multi-module projects, not just flat single-namespace ones.The old module-discovery + dependency-graph + topological-sort machinery is dropped: Rust resolves items crate-wide regardless of declaration order, so wrapped modules need no reordering.
Example
Input
main.rs+utils.rs→Tests
name_collisionsfixture (the exact reproduction from the issue) + regression test, including anrustccompile check.test_glob_imports/test_inline_modules_preservedto assert the new (correct) qualifier-preserving behavior.rustc(edition 2021).🤖 Generated with Claude Code