-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Propose to exchange ranges only when it is safe to do so #14432
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
Conversation
977ab28
to
5560c51
Compare
This could also be extended to situations where the ranges are used as an argument to a function/method call which accepts an
|
5560c51
to
184736f
Compare
Rebased on master |
Putting to draft, I want to double-check the lintcheck, it looks like we get some false negatives there. |
db80969
to
f532213
Compare
Much better. I added checking if the range to be modified is a method or function call argument, and if the target range would be suitable as well. @rustbot review |
r? clippy |
I added a second commit to fix an issue with parentheses lacking from some suggestions identified in a comment made tonight in #9908. |
443ee08
to
28b490f
Compare
r? clippy |
This comment has been minimized.
This comment has been minimized.
28b490f
to
3867236
Compare
Rebased |
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.
Thank you for fixing this as it's quite annoying currently.
clippy_lints/src/ranges.rs
Outdated
if let ExprKind::Index(_, index, _) = parent_expr.kind | ||
&& index.hir_id == expr.hir_id | ||
{ | ||
return true; | ||
} | ||
|
||
false | ||
} |
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 needs to check if Index<RangeType>
is implemented for the indexed type.
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.
Done, and I checked this for Index
or IndexMut
, depending of what we need.
clippy_lints/src/ranges.rs
Outdated
let expr_ty = inputs[input_idx]; | ||
// Check that the `expr` type is present only one, otherwise modifying just one of them it might be | ||
// risky if they are referenced using the same generic type for example. | ||
if inputs.iter().enumerate().all(|(n, ty)| n == input_idx || *ty != expr_ty) |
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 will need a TypeVisitor
over all other input parameters. Foo<T>
and such needs to be detected.
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.
Done with ty.walk()
, I don't think we need a visitor, if the range type doesn't appear within the generic arguments it doesn't matter if it is present, for example in a struct field of another argument, as they will not be used together (since we check that the range type is not referenced per-se but through constraints).
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.
TypeVisitor
actually visits the same things as Ty::walk
does, but walk
is the better thing here and I totally forgotten it existed.
3867236
to
2044877
Compare
0a28296
to
4c23383
Compare
Ping @Jarcho |
To limit false positives, the `range_plus_one` and `range_minus_one` lints will restrict themselves to situations where the iterator types can be easily switched from exclusive to inclusive or vice-versa. This includes situations where the range is used as an iterator, or is used for indexing. Also, when the range is used as a function or method call argument and the parameter type is generic over traits implemented by both kind of ranges, the lint will trigger. On the other hand, assignments of the range to variables, including automatically typed ones or wildcards, will no longer trigger the lint. However, the cases where such an assignment would benefit from the lint are probably rare. This fix doesn't prevent false positives from happening. A more complete fix would check if the obligations can be satisfied by the new proposed range type.
Those lints share the detection logic structure, but differed, probably because of an oversight, in lint emission: only one of them would take care of emitting parentheses around the suggestion if required. Factor the code into one function which checks for the right condition and emits the lint in an identical way.
4c23383
to
15fc993
Compare
Rebased since |
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.
Thank you.
To avoid false positives, the
range_plus_one
andrange_minus_one
lints will restrict themselves to situations where the iterator types can be easily switched from exclusive to inclusive or vice-versa. This includes situations where the range is used as an iterator, or is used for indexing.On the other hand, assignments of the range to variables, including automatically typed ones or wildcards, will no longer trigger the lint. However, the cases where such an assignment would benefit from the lint are probably rare.
In a second commit, the
range_plus_one
andrange_minus_one
logic are unified, in order to properly emit parentheses around the suggestion when needed.Fix #3307
Fix #9908
changelog: [
range_plus_one
,range_minus_one
]: restrict lint to cases where it is safe to switch the range typeEdit: as a consequence, this led to the removal of three
#[expect(clippy::range_plus_one)]
in the Clippy sources to avoid those false positives.