Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn on use x as x; #6444

Closed
jyn514 opened this issue Dec 12, 2020 · 8 comments
Closed

Warn on use x as x; #6444

jyn514 opened this issue Dec 12, 2020 · 8 comments
Labels
A-lint Area: New lints good-first-issue These issues are a good way to get started with Clippy L-complexity Lint: Belongs in the complexity lint group

Comments

@jyn514
Copy link
Member

jyn514 commented Dec 12, 2020

What it does

Warns when you rename an import to the original name. This is useless; you can just use it directly.

Categories (optional)

  • Kind: complexity or style maybe? It's definitely 'something simple but in a complex way', but I know a lot of people with allow(clippy::complexity) which I would prefer not happen.

What is the advantage of the recommended code over the original code

  • It removes useless dead code.

Drawbacks

None.

Example

https://github.com/rust-lang/rust/blob/c3ed6681ff8d446e68ce272be4bf66f4145f6e29/compiler/rustc_data_structures/src/sync.rs#L224

use std::rc::Weak as Weak;

Could be written as:

use std::rc::Weak;
@jyn514 jyn514 added the A-lint Area: New lints label Dec 12, 2020
@ebroto ebroto added L-complexity Lint: Belongs in the complexity lint group good-first-issue These issues are a good way to get started with Clippy labels Dec 13, 2020
@giraffate
Copy link
Contributor

I expected rustfmt to work, but for some reasons it doesn't seem to work.

@ebroto
Copy link
Member

ebroto commented Dec 16, 2020

I expected rustfmt to work, but for some reasons it doesn't seem to work.

You are right, rustfmt seems to take care of this, at least in the playground it automatically simplifies it.

@jyn514
Copy link
Member Author

jyn514 commented Dec 16, 2020

Hmm, that's weird, it didn't work on rustc (it must not, since rustfmt is enforced by tidy). I guess this should be a rustfmt bug report, then?

@ebroto
Copy link
Member

ebroto commented Dec 16, 2020

I guess this should be a rustfmt bug report, then?

I would say so, if the rustfmt.toml file in rustc didn't influence that behavior in some way

@jyn514
Copy link
Member Author

jyn514 commented Dec 16, 2020

Sounds good, thanks for the help debugging! I opened rust-lang/rustfmt#4594 instead.

@jyn514 jyn514 closed this as completed Dec 16, 2020
@criminosis
Copy link

criminosis commented Dec 16, 2020

I was tinkering on this today. Was going to be my first Rust PR but I hit a wall on it, curious if I could get some feedback if I was even on the right track?

impl LateLintPass<'_> for UselessImportRename {
    fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
        if_chain! {
            if let ItemKind::Use(use_path, UseKind::Single) = &item.kind;
            if let Some(last_use_path_segment) = use_path.segments.last();
            then {
                let final_import_name = item.ident;
                let original_import_name = last_use_path_segment.ident;
                //this only catches the desired case of a rename to different name, but
                //does not differentiate between a repeat rename and no rename
                let is_same_identifier = final_import_name == original_import_name;

                //TODO This can't be the right way since we're not actually working on character indices
                // here given binary to UTF-8 isn't 1:1. How do I get a SourceMap?
                let BytePos(item_end) = item.span.data().hi;
                let BytePos(path_end) = use_path.span.data().hi;

                //To differentiate between a rename and no rename check to see if our span 
                //could include a rename. If there is no rename then we'd expect this to only
                //have space for the terminating ;
                let is_renamed = path_end + 1 != item_end; 


                if is_same_identifier && is_renamed {
                
                span_lint_and_help(
                    cx,
                    USELESS_IMPORT_RENAME,
                    item.span,
                    "import uselessly renamed to its original name",
                    None,
                    "don't rename the import just use it directly without the as clause"
                );
            }
            }
        }
    }
}

Still a novice at Rust though so I'm probably missing out on the most idiomatic path. If anyone would be willing to give some pointers I'd appreciate it to carry over to my next issue on here I try to tackle.

  1. Was my usage of ident appropriate?
  2. Was there an easy way to get CharacterPos that I was just being oblivious to?

@ebroto
Copy link
Member

ebroto commented Dec 16, 2020

Hey @criminosis, thanks for your interest in improving Clippy! I'm sorry this was not actionable in Clippy in the end. I hope that at least it helped you to get acquainted with the code :)

In this particular case, I think it would have been simpler to use an early lint pass instead of a late one, since you don't need name resolution, type information, etc. here. Also, I'm not sure but I would say that using a late lint pass the information we need may not be there anymore!

Looking at how rustfmt seems to do it, if you use ast::UseTree, the prefix field is the path after use, and the first element of ast::UseTreeKind::Simple contains the ident after the as.

@criminosis
Copy link

Hey @ebroto ! Yeah I was thinking I didn't need to use late lint towards the end but didn't end up getting that far. I'll check out ast::UseTree for the future. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint Area: New lints good-first-issue These issues are a good way to get started with Clippy L-complexity Lint: Belongs in the complexity lint group
Projects
None yet
Development

No branches or pull requests

4 participants