Skip to content

Lint idea: detect circular module dependencies #5782

Open
@whatisaphone

Description

@whatisaphone

What it does

Forbids mutually recursive module dependencies within a crate.

Consider two modules, crate::foo and crate::bar. If foo uses bar, then bar must not use foo (and vice versa). At a high level, this enforces that the crate's internal dependency tree forms a DAG.

Categories (optional)

  • Kind: probably pedantic

What benefit of this lint over old code?

  • Keep a crate's internal dependency tree manageable
    • This helps in understanding the structure of an unfamiliar codebase
    • This can aid future refactors of a monolithic crate into smaller crates
  • Possibly speed up compilation by making it easier for rustc to internally parallelize builds of a single crate or divide a crate into isolated codegen units for incremental compilation

I stole the idea from tending, originally posted here. Further discussion in that thread

Prior art: eslint import/no-cycle

Drawbacks

Possibly too pedantic for some projects

Example

foo.rs

use crate::bar::bar;

struct Common {}

pub fn foo(common: &Common) {
    bar(common);
}

bar.rs

use crate::foo::Common;

pub fn bar(common: &Common) {}

Could be written as:

common.rs

struct Common {}

foo.rs

use crate::common::Common;
use crate::bar::bar;

pub fn foo(common: &Common) {
    bar(common);
}

bar.rs

use crate::common::Common;

pub fn bar(common: &Common) {}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: New lintsE-hardCall for participation: This a hard problem and requires more experience or effort to work on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions