Skip to content

Commit

Permalink
Merge pull request #19050 from ChayimFriedman2/iter-self
Browse files Browse the repository at this point in the history
fix: Don't suggest `into_iter().method()` on iterators
  • Loading branch information
Veykril authored Jan 27, 2025
2 parents 8ed9227 + b4508dc commit da33e7c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/tools/rust-analyzer/crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4961,6 +4961,17 @@ impl Type {
self.normalize_trait_assoc_type(db, &[], iterator_item.into())
}

pub fn impls_iterator(self, db: &dyn HirDatabase) -> bool {
let Some(iterator_trait) =
db.lang_item(self.env.krate, LangItem::Iterator).and_then(|it| it.as_trait())
else {
return false;
};
let canonical_ty =
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(Interner) };
method_resolution::implements_trait_unique(&canonical_ty, db, &self.env, iterator_trait)
}

/// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type
pub fn into_iterator_iter(self, db: &dyn HirDatabase) -> Option<Type> {
let trait_ = db.lang_item(self.env.krate, LangItem::IntoIterIntoIter).and_then(|it| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub(crate) fn complete_dot(
acc.add_method(ctx, dot_access, func, None, None)
});

if ctx.config.enable_auto_iter {
if ctx.config.enable_auto_iter && !receiver_ty.strip_references().impls_iterator(ctx.db) {
// FIXME:
// Checking for the existence of `iter()` is complicated in our setup, because we need to substitute
// its return type, so we instead check for `<&Self as IntoIterator>::IntoIter`.
Expand Down Expand Up @@ -1505,4 +1505,28 @@ fn main() {
"#]],
);
}

#[test]
fn no_iter_suggestion_on_iterator() {
check_no_kw(
r#"
//- minicore: iterator
struct MyIter;
impl Iterator for MyIter {
type Item = ();
fn next(&mut self) -> Option<Self::Item> { None }
}
fn main() {
MyIter.$0
}
"#,
expect![[r#"
me by_ref() (as Iterator) fn(&mut self) -> &mut Self
me into_iter() (as IntoIterator) fn(self) -> <Self as IntoIterator>::IntoIter
me next() (as Iterator) fn(&mut self) -> Option<<Self as Iterator>::Item>
me nth(…) (as Iterator) fn(&mut self, usize) -> Option<<Self as Iterator>::Item>
"#]],
);
}
}

0 comments on commit da33e7c

Please sign in to comment.