[useless_conversion]: don't lint if type parameter has unsatisfiable bounds for .into_iter() receiver#11301
Conversation
|
r? @dswij (rustbot has picked a reviewer for you, use r? to override) |
8e50a3c to
c9bfd20
Compare
|
We should probably check the rest of the bounds instead. I think |
Yeah, that's better, I changed it to that now. I ended up going with |
useless_conversion]: don't lint if type parameter has multiple boundsuseless_conversion]: don't lint if type parameter has unsatisfiable bounds for .into_iter() receiver
|
☔ The latest upstream changes (presumably #11239) made this pull request unmergeable. Please resolve the merge conflicts. |
|
Thank you. @bors r+ |
[`useless_conversion`]: don't lint if type parameter has unsatisfiable bounds for `.into_iter()` receiver Fixes #11300. Before this PR, clippy assumed that if it sees a `f(x.into_iter())` call and the type at that argument position is generic over any `IntoIterator`, then the `.into_iter()` call must be useless because `x` already implements `IntoIterator`, *however* this assumption is not right if the generic parameter has more than just the `IntoIterator` bound (because other traits can be implemented for the IntoIterator target type but not the IntoIterator implementor, as can be seen in the linked issue: `<[i32; 3] as IntoIterator>::IntoIter` satisfies `ExactSizeIterator`, but `[i32; 3]` does not). So, this PR makes it check that the type parameter only has a single `IntoIterator` bound. It *might* be possible to check if the type of `x` in `f(x.into_iter())` satisfies all the bounds on the generic type parameter as defined on the function (which would allow removing the `.into_iter()` call even with multiple bounds), however I'm not sure how to do that, and the current fix should always work. **Edit:** This PR has been changed to check if any of the bounds don't hold for the type of the `.into_iter()` receiver, so we can still lint in some cases. changelog: [`useless_conversion`]: don't lint `.into_iter()` if type parameter has multiple bounds
|
💔 Test failed - checks-action_test |
|
Hmm. That's an ICE: https://github.com/rust-lang/rust-clippy/actions/runs/6083961075/job/16505016344#step:8:3267 Backtrace |
|
Sorry, my bad. The code for getting the node args on method calls was slightly wrong. struct S1;
impl S1 {
pub fn foo<I: IntoIterator>(&self, _: I) {..}
}
S1.foo([1, 2].into_iter());The node args that we want are here: S1.foo(..)
^^^^^^^(this contains However we were getting the node args from here: S1.foo([1, 2].into_iter());
^^^^^^That didn't really make sense, the expression didn't even have any substs, and of course, using those to substitute the generic parameter list We didn't seem to have any tests for method calls that could have caught this, but I added some now. |
|
@bors r+ |
|
☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test |
Fixes #11300.
Before this PR, clippy assumed that if it sees a
f(x.into_iter())call and the type at that argument position is generic over anyIntoIterator, then the.into_iter()call must be useless becausexalready implementsIntoIterator, however this assumption is not right if the generic parameter has more than just theIntoIteratorbound (because other traits can be implemented for the IntoIterator target type but not the IntoIterator implementor, as can be seen in the linked issue:<[i32; 3] as IntoIterator>::IntoItersatisfiesExactSizeIterator, but[i32; 3]does not).So, this PR makes it check that the type parameter only has a single
IntoIteratorbound. It might be possible to check if the type ofxinf(x.into_iter())satisfies all the bounds on the generic type parameter as defined on the function (which would allow removing the.into_iter()call even with multiple bounds), however I'm not sure how to do that, and the current fix should always work.Edit: This PR has been changed to check if any of the bounds don't hold for the type of the
.into_iter()receiver, so we can still lint in some cases.changelog: [
useless_conversion]: don't lint.into_iter()if type parameter has multiple bounds