regexident / cargo-modules

Visualize/analyze a Rust crate's internal structure
Mozilla Public License 2.0
988 stars 48 forks source link

Incorrectly reported orphan module #302

Closed nigeleke closed 5 months ago

nigeleke commented 5 months ago

I have a module that is only used in a test configuration:

#[cfg(test)]
mod my_test_only_module;

fn main() {
    println!("Hello, world!");
}

cargo modules orphans reports this as an orphan, whereas cargo modules orphans --cfg-test does not (correctly so).

I would expect mod my_test_only_module to only be reported as a orphan in the case where: a) it wasn't conditionally used and b) where it has not been otherwise used.

Is there an additional argument I should apply when I perform the cargo modules orphans example and look for orphans in my non-test code?

regexident commented 5 months ago

Hi @nigeleke,

cargo-modules can only see what's included in the module tree (as loaded by rust-analyzer) for a particular check, i.e. either unconditional items or those with #[cfg(…)] macro attributes matched by the current config.

Rust's #[cfg(…)] macro attributes however are Turing complete (due to proc-macros) and thus undecidable, so any attempt to be "more smart" about them is futile, unfortunately.

For the case of #[cfg(test)] I suppose one could make cargo-modules have rust-analyzer load the project twice (and at the cost of double the loading time), once with and once without --cfg-test included and then only report orphans that were detected with both configs. But that still wouldn't address false positives reported due to say the use of #[cfg(target = …)].

One cannot simply filter out any orphans with a #[cfg(test)] attribute either, as those aren't loaded by rust-analyzer in the first place. And even if they were, what about #[cfg_attr(condition, test)], which in the general case is undecidable?