rust-lang / rust-lang/rust-clippy

Disallow item usage by configurable paths (possibly created by `extern crate self as xxx;`)

Open
#14,706 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

A-lint
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

What it does

There's a relatively common pattern in libraries that internally use their own procedural macros, which are also meant to be used externally. If these macros refer to any items from the public library, they need to do this via its public name, say xxx. However, if the xxx crate now uses these macros internally, they fail to build because xxx crate is not defined; you can only refer to it by crate. The easy solution is to add the following line to lib.rs:

extern crate self as xxx;

(see rust-lang/rust#56409)

But this creates a new problem: now you can refer to items in your xxx crate either by crate::foo::bar, or xxx::foo::bar. This creates inconsistency in the code style, especially when using something like group_imports = "StdExternalCrate" in your rustfmt config (which causes crate imports to be grouped separately from the external crates).

The idea is to create a lint that will disallow using xxx in paths if crate can be used instead and will lead to using the same type.

A possible extension that could improve the usefulness of the lint would be to make it configurable, similarly to missing_enforced_import_renames. For example, it might be undesirable to import some_crate_with_reexport::rand::Rng instead of rand::Rng, even if it would result in using the same type. This could be configurable like so:

path-renames = [
    { path = "xxx", rename = "crate" },
    { path = "some_crate_with_reexport::rand", rename = "rand" },
]
Advantage
  • More consistent code
  • Imports that are easier to track
Drawbacks

None that I can think of.

Example
extern crate self as xxx;

use crate::foo::bar;
use xxx::foo::baz;

Could be written as:

extern crate self as xxx;

use crate::foo:bar;
use crate::foo:baz;

If this lint is something that could be useful, I'm happy to implement it.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing how the existing missing_enforced_import_renames configuration is implemented, then examine the lib.rs example involving extern crate self as xxx. Define the lint behavior for equivalent paths and determine how the proposed path-renames configuration should represent both crate aliases and re-exported paths.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.