Skip to content

Commit 0234d7c

Browse files
committed
Fix skipiter not applicable in autoderef
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> ```
1 parent 7c8955d commit 0234d7c

File tree

1 file changed

+37
-3
lines changed
  • src/tools/rust-analyzer/crates/ide-completion/src/completions

1 file changed

+37
-3
lines changed

src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ pub(crate) fn complete_dot(
9191
// its return type, so we instead check for `<&Self as IntoIterator>::IntoIter`.
9292
// Does <&receiver_ty as IntoIterator>::IntoIter` exist? Assume `iter` is valid
9393
let iter = receiver_ty
94-
.strip_references()
95-
.add_reference(hir::Mutability::Shared)
96-
.into_iterator_iter(ctx.db)
94+
.autoderef(ctx.db)
95+
.map(|ty| ty.strip_references().add_reference(hir::Mutability::Shared))
96+
.find_map(|ty| ty.into_iterator_iter(ctx.db))
9797
.map(|ty| (ty, SmolStr::new_static("iter()")));
9898
// Does <receiver_ty as IntoIterator>::IntoIter` exist?
9999
let into_iter = || {
@@ -1466,6 +1466,40 @@ fn foo() {
14661466
me into_iter().nth(…) (as Iterator) fn(&mut self, usize) -> Option<<Self as Iterator>::Item>
14671467
"#]],
14681468
);
1469+
check_no_kw(
1470+
r#"
1471+
//- minicore: iterator, deref
1472+
struct Foo;
1473+
impl Foo { fn iter(&self) -> Iter { Iter } }
1474+
impl IntoIterator for &Foo {
1475+
type Item = ();
1476+
type IntoIter = Iter;
1477+
fn into_iter(self) -> Self::IntoIter { Iter }
1478+
}
1479+
struct Ref;
1480+
impl core::ops::Deref for Ref {
1481+
type Target = Foo;
1482+
fn deref(&self) -> &Self::Target { &Foo }
1483+
}
1484+
struct Iter;
1485+
impl Iterator for Iter {
1486+
type Item = ();
1487+
fn next(&mut self) -> Option<Self::Item> { None }
1488+
}
1489+
fn foo() {
1490+
Ref.$0
1491+
}
1492+
"#,
1493+
expect![[r#"
1494+
me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
1495+
me into_iter() (as IntoIterator) fn(self) -> <Self as IntoIterator>::IntoIter
1496+
me iter() fn(&self) -> Iter
1497+
me iter().by_ref() (as Iterator) fn(&mut self) -> &mut Self
1498+
me iter().into_iter() (as IntoIterator) fn(self) -> <Self as IntoIterator>::IntoIter
1499+
me iter().next() (as Iterator) fn(&mut self) -> Option<<Self as Iterator>::Item>
1500+
me iter().nth(…) (as Iterator) fn(&mut self, usize) -> Option<<Self as Iterator>::Item>
1501+
"#]],
1502+
);
14691503
}
14701504

14711505
#[test]

0 commit comments

Comments
 (0)