Skip to content

Commit b4508dc

Browse files
Don't suggest into_iter().method() on iterators
1 parent ad0aea4 commit b4508dc

File tree

2 files changed

+36
-1
lines changed
  • src/tools/rust-analyzer/crates

2 files changed

+36
-1
lines changed

src/tools/rust-analyzer/crates/hir/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4940,6 +4940,17 @@ impl Type {
49404940
self.normalize_trait_assoc_type(db, &[], iterator_item.into())
49414941
}
49424942

4943+
pub fn impls_iterator(self, db: &dyn HirDatabase) -> bool {
4944+
let Some(iterator_trait) =
4945+
db.lang_item(self.env.krate, LangItem::Iterator).and_then(|it| it.as_trait())
4946+
else {
4947+
return false;
4948+
};
4949+
let canonical_ty =
4950+
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
4951+
method_resolution::implements_trait_unique(&canonical_ty, db, &self.env, iterator_trait)
4952+
}
4953+
49434954
/// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type
49444955
pub fn into_iterator_iter(self, db: &dyn HirDatabase) -> Option<Type> {
49454956
let trait_ = db.lang_item(self.env.krate, LangItem::IntoIterIntoIter).and_then(|it| {

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ pub(crate) fn complete_dot(
8989
acc.add_method(ctx, dot_access, func, None, None)
9090
});
9191

92-
if ctx.config.enable_auto_iter {
92+
if ctx.config.enable_auto_iter && !receiver_ty.strip_references().impls_iterator(ctx.db) {
9393
// FIXME:
9494
// Checking for the existence of `iter()` is complicated in our setup, because we need to substitute
9595
// its return type, so we instead check for `<&Self as IntoIterator>::IntoIter`.
@@ -1505,4 +1505,28 @@ fn main() {
15051505
"#]],
15061506
);
15071507
}
1508+
1509+
#[test]
1510+
fn no_iter_suggestion_on_iterator() {
1511+
check_no_kw(
1512+
r#"
1513+
//- minicore: iterator
1514+
struct MyIter;
1515+
impl Iterator for MyIter {
1516+
type Item = ();
1517+
fn next(&mut self) -> Option<Self::Item> { None }
1518+
}
1519+
1520+
fn main() {
1521+
MyIter.$0
1522+
}
1523+
"#,
1524+
expect![[r#"
1525+
me by_ref() (as Iterator) fn(&mut self) -> &mut Self
1526+
me into_iter() (as IntoIterator) fn(self) -> <Self as IntoIterator>::IntoIter
1527+
me next() (as Iterator) fn(&mut self) -> Option<<Self as Iterator>::Item>
1528+
me nth(…) (as Iterator) fn(&mut self, usize) -> Option<<Self as Iterator>::Item>
1529+
"#]],
1530+
);
1531+
}
15081532
}

0 commit comments

Comments
 (0)