Skip to content

Lint against recursive imports (paths that start at a previous import) #17429

Description

@jrose-signal

What it does

When reading a use declaration, you have to know what the first component refers to. If it starts with :: or crate, it's definitely an absolute path; if it starts with self or super, it's definitely a relative path. Otherwise, there are three choices:

  1. it's an external crate
  2. it's a submodule* declared in this file
  3. it's something else I've already imported

* okay technically it could be a type

Usually I can distinguish between (1) and (2), but with (3) all bets are off, whether it's from inside the current crate or from an external crate. (Some may disagree here and say "it's okay for current-crate imports" or "it's okay for external-crate imports".) I'd rather lint against them.

Exceptions (should not lint on these):

  • the recursive use is not in the same scope as the one it references
  • (maybe?) the referenced use is pub but the recursive one is not - pub use is similar to declaring a submodule, so it's a "faux (2)" case

Advantage

  • Easier for a human to figure out a use declaration
  • Fewer total use declarations, if you're okay with self

Drawbacks

  • Longer import lines
  • Special rule for use that doesn't apply to the rest of the code (where it is common to use relative paths often and absolute paths occasionally).

Example

use external_crate::foo;
use foo::Bar;

Could be written as:

use external_crate::foo;
use external_crate::foo::Bar;

or

use external_crate::foo::{self, Bar};

Comparison with existing lints

Additional Context

No response

Metadata

Metadata

Assignees

Labels

A-lintArea: New lints

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions