-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add redundant type annotations lint #10570
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @xFrednet (or someone else) soon. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
ddc455a
to
4770ee1
Compare
☔ The latest upstream changes (presumably #10534) made this pull request unmergeable. Please resolve the merge conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Welcome to Clippy. Thank you for your patience while waiting on a review!
I've left some review comments. Please don't be discouraged by them, I believe this lint can become quite complex depending on how detailed and how many edge cases we want to catch. Please reach out if you require any further assistance. :)
fffd85b
to
5ae56f0
Compare
Thanks for the review! |
e858255
to
5977676
Compare
You're welcome. Are you still working on the implementation or is the branch ready for another review? :) |
I'm still working on it. Right now I've problems with Or when is a type annotation useful in case of a pub enum LitKind {
/// A string literal (`"foo"`). The symbol is unescaped, and so may differ
/// from the original token's symbol.
Str(Symbol, StrStyle),
/// A byte string (`b"foo"`). Not stored as a symbol because it might be
/// non-utf8, and symbols only allow utf8 strings.
ByteStr(Lrc<[u8]>, StrStyle),
/// A byte char (`b'f'`).
Byte(u8),
/// A character literal (`'a'`).
Char(char),
/// An integer literal (`1`).
Int(u128, LitIntType),
/// A float literal (`1.0`, `1f64` or `1E10f64`). The pre-suffix part is
/// stored as a symbol rather than `f64` so that `LitKind` can impl `Eq`
/// and `Hash`.
Float(Symbol, LitFloatType),
/// A boolean literal (`true`, `false`).
Bool(bool),
/// Placeholder for a literal that wasn't well-formed in some way.
Err,
} In almost all these cases we can say that the annotation is redundant, or am I missing anything? |
9b60cbf
to
a29fd4f
Compare
☔ The latest upstream changes (presumably #10601) made this pull request unmergeable. Please resolve the merge conflicts. |
I don't think there is an easy way to map it. You could request the type of the expression, but that will probably not help too much.
A type annotation is useful or even required when the literal is unsuffixed. For example |
a29fd4f
to
b0405c7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally speaking, I think this is a good start, which we could actually merge as a minimum viable product. There are still several examples that could be improved. However, most of them seem a bit complicated to fix and the question is how much benefit we'll get from them. It should be fine as is, since all ToDos are false negatives.
What are your thoughts? Do you want to try perfecting it in this PR or get this merge ready and create follow-ups? (Assuming, you're still interested in the lint)
|
||
let _return: u32 = new_pie.return_an_int(); | ||
|
||
let _return: String = String::from("test"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This currently doesn't trigger a lint, even if the function comment says it should. I'm not quite sure why, as String::new()
etc are covered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, I missed that, thanks!
I digged into it a bit, it turns out it is related to generics.
When I do cx.tcx.type_of(func_defid)
of the function, I get EarlyBinder(fn(T) -> Self {<Self as std::convert::From<T>>::from})
If I then execute subst_identity
or skip_binder
on this, I get fn(T) -> Self {<Self as std::convert::From<T>>::from}
Then, when I do func_ty.fn_sig(cx.tcx).output()
where func_ty
is the type I wrote previously, I get Binder(Self, [])
, then I interpret the return type as Self
instead of String
.
Do you know what I could use in this case? I tried having a look at other lints but I was not able to find anything, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @xFrednet , do you have any clue on this? Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I missed your question earlier 😅. I'm not totally sure about this one, but you might want to take a look at:
type_dependent_def
to resolve the method target- Maybe qpath_res to resolve
Self
?
If both of these don't work, I'd probably ask on Zulip the others might have a good idea for this one :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I missed your question earlier 😅. I'm not totally sure about this one, but you might want to take a look at:
type_dependent_def
to resolve the method target- Maybe qpath_res to resolve
Self
?If both of these don't work, I'd probably ask on Zulip the others might have a good idea for this one :)
I've tried the two methods you suggested without any luck. I've asked on Zulip, let's see.
Thanks!
Hello @xFrednet , thanks again. I'm still interested and I plan to perfecting this PR (at least adding support for primitive types and the suggestions you mentioned in the previous reviews). |
Hello @xFrednet , there's still the problem with the |
db33978
to
0583a29
Compare
Hello @xFrednet, I think this is ready for review. We miss a couple of things which I think they could be added in the future, like:
Thanks! |
be50a5f
to
1ef6023
Compare
As long as we don't have false positives and only false negatives, that's totally fine :). Could you add this limitation, as well as the complex types and path one into the lint documentation? I like to use a
We should make sure that normal function calls are also detected. For one, because they're used quite often and because it should be a simple addition. I can mark the required changes in the next review :)
Complex types are sadly complex to lint. I've been contemplating, how to best handle lints for these, for a different project. I sadly haven't found a good option. This is to say, that it's fine if these are not caught, probably. I guess that Clippy has quite a few lints that can't handle these :)
I believe that should be fine. Such a pattern is rarely used in the projects I'm using. We can leave this as an improvement for the future :)
You're very welcome, thank you for working on Clippy! I'll review this PR in the upcoming week :) |
☔ The latest upstream changes (presumably #10810) made this pull request unmergeable. Please resolve the merge conflicts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This version looks good to me. I would say, it only requires the limitations section and a rebase. Then we can merge it! :)
ac43a4c
to
c427a17
Compare
I think I've addressed all your comments and rebased to Thanks! |
c427a17
to
a31df5c
Compare
There still seems to be a conflict, could you resolve that one?
It's not mandatory, but would be nice, 1 - 5 commits would be a good balance :) I intend to review this over the weekend :) |
5d4cee7
to
3df2a43
Compare
Ok I've rebased to master and reduced the amount of commits, thanks! |
3df2a43
to
a9b468f
Compare
Rebased again :D |
This version looks good to me. Thank you for all the work you put into this lint! I appreciate it! @bors r+ |
☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test |
Hello, I'm trying to add the
redundat_type_annotations
lint.It's still WIP but I'd like to start gathering some feedbacks to be sure that I'm not doing things 100% wrong :)
Right now it still misses lints like:
let foo: u32 = 5_u32
,let foo: String = STest2::func()
let foo: String = self.func()
(MethodCall
)I've some problems regarding the second example above, in the
init
part of theLocal
I have:And I'm not sure how to get the return type of the function
STest2::func()
since the resolved pathDefId
points to the struct itself and not the function. Do you have any idea on how I could get this information in this case?Thanks!
changelog: changelog: [
redundant_type_annotations
]: New lint to warn on redundant type annotationsfixes #9155