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.