diff options
| author | Chayim Refael Friedman <chayimfr@gmail.com> | 2025-01-27 18:48:20 +0200 |
|---|---|---|
| committer | Chayim Refael Friedman <chayimfr@gmail.com> | 2025-01-27 18:48:20 +0200 |
| commit | b4508dc406f0def337bb4a6590f45dd0327a068e (patch) | |
| tree | 1e980ffcd189016813739fa35ce0fd5764ac59de | |
| parent | ad0aea432356b5687684a370d4c309989de1a549 (diff) | |
| download | rust-b4508dc406f0def337bb4a6590f45dd0327a068e.tar.gz rust-b4508dc406f0def337bb4a6590f45dd0327a068e.zip | |
Don't suggest `into_iter().method()` on iterators
| -rw-r--r-- | src/tools/rust-analyzer/crates/hir/src/lib.rs | 11 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs | 26 |
2 files changed, 36 insertions, 1 deletions
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 5b35b0168ac..01aa7e0b16c 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -4940,6 +4940,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| { diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs index d12654665ce..0557265f235 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/dot.rs @@ -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`. @@ -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> + "#]], + ); + } } |
