Allow incrementally adding items to a module


#1

Currently, one can incrementally implement types via macros by opening an impl block multiple times:

pub struct A;
impl A { fn foo() {} }
impl A { fn bar() {} }

I have macros that incrementally implement types this way and that works fine. However, one cannot do the same thing for modules:

// parent module
pub struct A;
impl A { fn foo() {} }
impl A { fn bar() {} }
#[cfg(test)] mod A_tests { #[test] fn foo_test() {} }
#[cfg(test)] mod A_tests { #[test] fn bar_test() {} } // ERROR

I have macros that incrementally implement the APIs for some types, but these macros also add tests for these APIs. I would like to put these tests inside the same module (e.g. mod tests) but I cannot open the module from its parent multiple times to add more items to it.

The workaround I use is to just add the tests to uniquely name modules. My Rust crates then end up with hundreds of modules for tests builds, which then are compiled in hundreds of compilation units. This breaks linkers in some platforms when rust pass them thousands of rcgus when running cargo test.

The alternative I’ve tried is to use uniquely named tests in the parent module, but then if many types are implemented in the same parent module, that module ends up containing thousands of tests.

Another alternative I’ve tried is to split the tests from the implementation. This resulted into people forgetting to tests some of the APIs, which resulted in many bugs.

Why is the reason for the discrepancy between being able to incrementally add items to a type, and incrementally being able to add items to a module (from its parent module at least) ?


#2

Maybe something like, “partial mod” (akin to C# “partial class”) would be helpful for this? If there is some limitation as to why just using “mod” again to re-open/add to a module, then perhaps “partial mod” could be introduced to the language for this use-case?