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 redundant / needless type annotations #9155

Closed
shepmaster opened this issue Jul 12, 2022 · 17 comments · Fixed by #10570
Closed

Warn on redundant / needless type annotations #9155

shepmaster opened this issue Jul 12, 2022 · 17 comments · Fixed by #10570
Assignees
Labels
A-lint Area: New lints good-first-issue These issues are a good way to get started with Clippy L-suggestion Lint: Improving, adding or fixing lint suggestions

Comments

@shepmaster
Copy link
Member

shepmaster commented Jul 12, 2022

What it does

Warns about needless / redundant type annotations.

Lint Name

redundant_type_annotation

Category

style, pedantic

Advantage

Code is more idiomatic, shorter, and easier to modify.

Drawbacks

Types may be added by some novice Rust developers as hints to help remember what type is present.

Example

let foo: String = String::new();

Could be written as:

let foo = String::new();
@shepmaster shepmaster added the A-lint Area: New lints label Jul 12, 2022
@giraffate giraffate added the good-first-issue These issues are a good way to get started with Clippy label Jul 12, 2022
@flip1995 flip1995 added the L-suggestion Lint: Improving, adding or fixing lint suggestions label Jul 12, 2022
@smoelius
Copy link
Contributor

Related: #7081

@SoryRawyer
Copy link

SoryRawyer commented Aug 27, 2022

hi folks, is this issue ready to be picked up? I was thinking of looking into this issue as my first opportunity to cross the clippy user/clippy contributor barrier but before I do I wanted to see (1) if I'd be stepping on anyone's toes, (2) if there were any outstanding questions about this issue, and (3) if you all had any tips for where to look to get started in addition to the adding lints docs page. thanks!

@llogiq
Copy link
Contributor

llogiq commented Aug 28, 2022

Just comment <at>rustbot claim, but with the <at> replaced by @ to claim the issue.

If you are unsure how to proceed, feel free to comment your questions on the issue or in the clippy channel on the rust-lang zulip.

@llogiq
Copy link
Contributor

llogiq commented Aug 28, 2022

As for open questions, I'd suggest picking the pedantic lint group first, and start with linting on (method) calls with a non-generic return type.

@SoryRawyer
Copy link

@rustbot claim

@SoryRawyer
Copy link

@rustbot release-assignment

@paul-ohl
Copy link

Hi everyone!

If I succeed, this will be my first contribution to any opensource software, so hopefully it goes well!

@paul-ohl
Copy link

@rustbot claim

@paul-ohl
Copy link

paul-ohl commented Feb 9, 2023

I am sorry for the amount of time this issue is taking me, but I think I'm on the right track, and I'm still working on it!

@paul-ohl
Copy link

paul-ohl commented Mar 7, 2023

It seems pretty logical to me that this lint should also flag the use of redundant type annotations in the case of a struct, but I want to make sure, is it the case? example:

let a_struct: A = A;
let b_struct: B = B::new();

@paul-ohl
Copy link

paul-ohl commented Mar 7, 2023

Actually, now that I think about it, when is it useful to actually have the type annotation? Because it feels like it's always redundant, except maybe for numbers? But even then it could be considered redundant. So is this what I should check for? Or am I missing something?

@shepmaster
Copy link
Member Author

Effectively, I'd expect that the lint would have the same behavior (but likely a vastly different implementation) as removing the type annotation and then seeing if the code still compiles. I think that Iterator::collect is a key example:

use std::iter;

fn main() {
    let type_required: Vec<()> = iter::once(()).collect();
    dbg!(type_required);

    let type_not_required: Vec<()> = iter::once(()).collect();
    usage(type_not_required);
}

fn usage(v: Vec<()>) {
    dbg!(v);
}

@paul-ohl
Copy link

I'm very sorry, but I think this is not for me.

@paul-ohl
Copy link

@rustbot release-assignment

@AlessioC31
Copy link
Contributor

@rustbot claim

@AlessioC31
Copy link
Contributor

AlessioC31 commented Mar 27, 2023

As for open questions, I'd suggest picking the pedantic lint group first, and start with linting on (method) calls with a non-generic return type.

Hello, I'm trying to work on this, it is my first lint for clippy :)

I wanted to start by linting on function calls with non generic return types, for example

fn f() -> String {
    String::new()
}

...

let a: String = f();

When I dump the HIR, for the let statement, when I look at the init part, I see:

init: Some(
                Expr {
                    hir_id: HirId(DefId(0:3 ~ playground[15d0]::main).4),
                    kind: Call(
                        Expr {
                            hir_id: HirId(DefId(0:3 ~ playground[15d0]::main).5),
                            kind: Path(
                                Resolved(
                                    None,
                                    Path {
                                        span: src/main.rs:8:24: 8:25 (#0),
                                        res: Def(
                                            Fn,
                                            DefId(0:4 ~ playground[15d0]::f),
                                        ),
                                        segments: [
                                            PathSegment {
                                                ident: f#0,
                                                hir_id: HirId(DefId(0:3 ~ playground[15d0]::main).6),
                                                res: Def(
                                                    Fn,
                                                    DefId(0:4 ~ playground[15d0]::f),
                                                ),
                                                args: None,
                                                infer_args: true,
                                            },
                                        ],
                                    },
                                ),
                            ),
                            span: src/main.rs:8:24: 8:25 (#0),
                        },
                        [],
                    ),
                    span: src/main.rs:8:24: 8:27 (#0),
                },
            ),

How would you get the returned type from the function calls from here? Is there anything I can use in the ctx?

Also, which check function would you use in the LateLintPass? I started with the check_local but I'm open to suggestions :D

Thanks!

@AlessioC31
Copy link
Contributor

AlessioC31 commented Mar 28, 2023

Ok I managed to get it to work somehow, for now it lints on function calls with non generic types.
Commit: AlessioC31@a967474

Do you think that I could add more test cases? (As it's my first lint I'm not 100% of the assumptions I'm doing when checking the types, e.g. it doesn't work with method calls and with primitive types)
Maybe there's a less cumbersome way to do it? :D

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-suggestion Lint: Improving, adding or fixing lint suggestions
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants