mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-03 05:13:35 +00:00
Merge pull request #19050 from ChayimFriedman2/iter-self
fix: Don't suggest `into_iter().method()` on iterators
This commit is contained in:
commit
b27c5b4cae
2 changed files with 36 additions and 1 deletions
|
|
@ -4961,6 +4961,17 @@ impl Type {
|
||||||
self.normalize_trait_assoc_type(db, &[], iterator_item.into())
|
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
|
/// Resolves the projection `<Self as IntoIterator>::IntoIter` and returns the resulting type
|
||||||
pub fn into_iterator_iter(self, db: &dyn HirDatabase) -> Option<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| {
|
let trait_ = db.lang_item(self.env.krate, LangItem::IntoIterIntoIter).and_then(|it| {
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ pub(crate) fn complete_dot(
|
||||||
acc.add_method(ctx, dot_access, func, None, None)
|
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:
|
// FIXME:
|
||||||
// Checking for the existence of `iter()` is complicated in our setup, because we need to substitute
|
// 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`.
|
// 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>
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue