-
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
Improve redundant_slicing
lint
#8218
Conversation
r? @camsteffen (rust-highfive has picked a reviewer for you, use r? to override) |
c242ef2
to
2c1f2ff
Compare
Linting "slice instead of deref" is more picky than linting "slice has no effect", so I think this should be a new lint. Named And then I'm not sure if it should be pedantic or restriction. I think some people may actually prefer the slicing operator since it makes the type of the expression more apparent. There's also a third option - to use |
That is a fair point. I'd say I'd say |
@rust-lang/clippy thoughts? Should |
Sounds good. That would be |
restriction I think. Pedantic is kinda fine but I think we need to have a reason for it If it's going to be a restriction lint I suspect we should wait for people to ask us for it |
#7257 kind of asked for it. Although I'm sure it was assuming letting auto-deref take care of things rather than explicitly dereferencing. |
I'm also thinking restriction - feels opinionated/controversial. But I do think having the lint would be good, especially since the implementation easily fits in with redundant_slicing. |
bd637f2
to
ac282d8
Compare
What do you think about the name Also don't forget to add a test case where the sliced expression is |
I would say |
Between the two lints almost all slicing with The problem with the |
WRT naming, I think it's fine to assume the convention: index operator with a range is called "slicing" and it returns a slice. I think |
There's still the case where the type has full slicing that changes the type, but doesn't impl |
Fair point. How about |
That works. |
014b0e7
to
70bc0cf
Compare
@@ -520,7 +520,7 @@ fn extract_clippy_version_value(cx: &LateContext<'_>, item: &'_ Item<'_>) -> Opt | |||
if_chain! { | |||
// Identify attribute | |||
if let ast::AttrKind::Normal(ref attr_kind, _) = &attr.kind; | |||
if let [tool_name, attr_name] = &attr_kind.path.segments[..]; | |||
if let [tool_name, attr_name] = &*attr_kind.path.segments; |
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.
I'd prefer not to "fix" all these since it's a restriction lint. Please also revert any such changes in the tests unless you think it is improving the quality of the test.
LL | let _ = &(&v[..])[..]; // Outer borrow is redundant | ||
| ^^^^^^^^^^^^^ help: use the original value instead: `(&v[..])` | ||
LL | let _ = &(&*v)[..]; // Outer borrow is redundant | ||
| ^^^^^^^^^^ help: use the original value instead: `(&*v)` |
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.
It's been a while since I looked at this PR. I believe if a *
is suggested, it should be a deref_by_slicing
case?
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.
The suggested change is from &(&*v)[..]
-> (&*v)
where v
is a Vec<_>
. The lint isn't suggesting to add a dereference here, it was already there to start with.
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.
Apparrently I can't tell the difference between the commit diff and the rust output diff 🤦. But what about the error at the bottom of this file (same question)?
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.
I'll assume you're referring to &slice_ref[..]
. slice_ref
is a &&[_]
. Full slicing is the same as just removing a reference in this case.
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.
Below that is
error: redundant slicing of the whole range
--> $DIR/redundant_slicing.rs:45:13
|
LL | let _ = (&bytes[..]).read_to_end(&mut vec![]).unwrap();
| ^^^^^^^^^^^^ help: reborrow the original value instead: `(&*bytes)`
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.
If anything the previous one is much more of a deref-by-slicing. This is very much a slice-to-get-a-new-value-so-we-don't-modify-the-current-one (really flows of the tongue there).
I think leaving redundant_slicing
to only handle cases where it's doing nothing and can be fully removed is fine, but deref_by_slicing
is not really a good spot to put the remaining cases. That would mean having a name for a new lint (as precise as the name earlier is, I don't want to fight for longest lint name).
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.
You could call it slice-to-deref-to-get-a-new-borrow-of... You can put a lot of new names on it but ultimately it just changes &[u8]
to [u8]
before the borrow operator applies. I don't see how it is not a deref. The suggestion literally replaces the slicing with a deref operator which has the exact same effect. If I enabled deref_by_slicing
in my code, I'd consider it a bug if this case were not included.
I think leaving redundant_slicing to only handle cases where it's doing nothing and can be fully removed is fine
That is the most important thing since it is warn-by-default.
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.
We're talking about two slightly different things here. I'm talking about the entire expression &x[..]
not just x[..]
. x[..]
is just *x.index(..)
so it will almost always be a deref. In this case the deref part is the only effect being used, so I guess that fits under deref_by_slicing
.
I'm not sure why you don't take issue with the &&T
-> &T
case being under redundant_slicing
.
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.
I'm not sure why you don't take issue with the
&&T
->&T
case being underredundant_slicing
.
Honestly I was just focusing on the other case. Yeah that one probably should be treated in the same way.
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.
I'll move that all to deref_as_slice
then. I still think the re-borrowing case is different enough to warrant it's own lint, but that can be dealt with at another time.
☔ The latest upstream changes (presumably #8409) made this pull request unmergeable. Please resolve the merge conflicts. |
2308856
to
46353f8
Compare
Thanks! @bors r+ |
📌 Commit 46353f8 has been approved by |
@bors r- Sorry, probably should squash some? |
* Lint when slicing triggers auto-deref * Lint when slicing returns the same type as dereferencing
46353f8
to
7fad2f9
Compare
7fad2f9
to
7724d67
Compare
@bors r+ |
📌 Commit 7724d67 has been approved by |
☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test |
fixes #7972
fixes #7257
This can supersede #7976
changelog: Fix suggestion for
redundant_slicing
when re-borrowing for a method callchangelog: New lint
deref_as_slicing