Skip to content

Commit 6d8903a

Browse files
committed
fix: infer for-loop item type with IntoIterator and Iterator
1 parent ad752bd commit 6d8903a

File tree

5 files changed

+29
-3
lines changed

5 files changed

+29
-3
lines changed

crates/hir-expand/src/name.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ pub mod known {
263263
Iterator,
264264
IntoIterator,
265265
Item,
266+
IntoIter,
266267
Try,
267268
Ok,
268269
Future,

crates/hir-ty/src/infer.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,12 @@ impl<'a> InferenceContext<'a> {
883883
fn resolve_into_iter_item(&self) -> Option<TypeAliasId> {
884884
let path = path![core::iter::IntoIterator];
885885
let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
886+
self.db.trait_data(trait_).associated_type_by_name(&name![IntoIter])
887+
}
888+
889+
fn resolve_iterator_item(&self) -> Option<TypeAliasId> {
890+
let path = path![core::iter::Iterator];
891+
let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
886892
self.db.trait_data(trait_).associated_type_by_name(&name![Item])
887893
}
888894

crates/hir-ty/src/infer/expr.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,10 @@ impl<'a> InferenceContext<'a> {
207207
}
208208
&Expr::For { iterable, body, pat, label } => {
209209
let iterable_ty = self.infer_expr(iterable, &Expectation::none());
210-
let pat_ty =
210+
let into_iter_ty =
211211
self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item());
212+
let pat_ty =
213+
self.resolve_associated_type(into_iter_ty, self.resolve_iterator_item());
212214

213215
self.infer_pat(pat, &pat_ty, BindingMode::default());
214216
self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {

crates/hir-ty/src/tests/traits.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,10 @@ fn test() {
279279
pub mod iter {
280280
pub trait IntoIterator {
281281
type Item;
282+
type IntoIter: Iterator<Item = Self::Item>;
283+
}
284+
pub trait Iterator {
285+
type Item;
282286
}
283287
}
284288
pub mod prelude {
@@ -297,7 +301,13 @@ pub mod collections {
297301
}
298302
299303
impl<T> IntoIterator for Vec<T> {
300-
type Item=T;
304+
type Item = T;
305+
type IntoIter = IntoIter<T>;
306+
}
307+
308+
struct IntoIter<T> {}
309+
impl<T> Iterator for IntoIter<T> {
310+
type Item = T;
301311
}
302312
}
303313
"#,

crates/ide/src/inlay_hints.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2024,7 +2024,14 @@ impl<T> Vec<T> {
20242024
}
20252025
20262026
impl<T> IntoIterator for Vec<T> {
2027-
type Item=T;
2027+
type Item = T;
2028+
type IntoIter = IntoIter<T>;
2029+
}
2030+
2031+
struct IntoIter<T> {}
2032+
2033+
impl<T> Iterator for IntoIter<T> {
2034+
type Item = T;
20282035
}
20292036
20302037
fn main() {

0 commit comments

Comments
 (0)