Skip to content

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

Open
@m4tx

Description

@m4tx

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lintArea: New lints

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions