-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Fix skipiter not applicable in autoderef #21095
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
Example
---
**std example**:
```rust
fn foo(nums: std::rc::Rc<[i32]>) {
nums.$0
}
```
---
**minicore example**:
```rust
struct Foo;
impl Foo { fn iter(&self) -> Iter { Iter } }
impl IntoIterator for &Foo {
type Item = ();
type IntoIter = Iter;
fn into_iter(self) -> Self::IntoIter { Iter }
}
struct Ref;
impl core::ops::Deref for Ref {
type Target = Foo;
fn deref(&self) -> &Self::Target { &Foo }
}
struct Iter;
impl Iterator for Iter {
type Item = ();
fn next(&mut self) -> Option<Self::Item> { None }
}
fn foo() {
Ref.$0
}
```
**Before this PR**
```text
me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
me into_iter() (as IntoIterator) fn(self) -> <Self as IntoIterator>::IntoIter
me iter() fn(&self) -> Iter
```
**After this PR**
```text
me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
me into_iter() (as IntoIterator) fn(self) -> <Self as IntoIterator>::IntoIter
me iter() fn(&self) -> Iter
me iter().by_ref() (as Iterator) fn(&mut self) -> &mut Self
me iter().into_iter() (as IntoIterator) fn(self) -> <Self as IntoIterator>::IntoIter
me iter().next() (as Iterator) fn(&mut self) -> Option<<Self as Iterator>::Item>
me iter().nth(…) (as Iterator) fn(&mut self, usize) -> Option<<Self as Iterator>::Item>
```
| // its return type, so we instead check for `<&Self as IntoIterator>::IntoIter`. | ||
| // Does <&receiver_ty as IntoIterator>::IntoIter` exist? Assume `iter` is valid | ||
| let iter = receiver_ty | ||
| .strip_references() |
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.
Won't this break cases where we have a type T that derefs to U where T has interesting impls but U does not?
I think the proper fix here is to walk the autoderef chain and find the first candidate that impls IntoIterator instead
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 think the proper fix here is to walk the autoderef chain and find the first candidate that impls
IntoIteratorinstead
Can't .find_map(|ty| ty.into_iterator_iter(ctx.db)) do it?
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.
Ah I think I misunderstood what autoderef does, I thought it was a single step, not the whole chain sorry
Veykril
left a comment
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.
Thanks!
Example
std example:
minicore example:
Before this PR
After this PR