diff --git a/crates/hir-ty/src/next_solver/infer/context.rs b/crates/hir-ty/src/next_solver/infer/context.rs index 270bc73d5f53..5ac3432b3aa9 100644 --- a/crates/hir-ty/src/next_solver/infer/context.rs +++ b/crates/hir-ty/src/next_solver/infer/context.rs @@ -348,10 +348,28 @@ impl<'db> rustc_type_ir::InferCtxtLike for InferCtxt<'db> { fn opaques_with_sub_unified_hidden_type( &self, - _ty: TyVid, + ty: TyVid, ) -> Vec> { - // FIXME: I guess we are okay without this for now since currently r-a lacks of - // detailed checks over opaque types. Might need to implement this in future. - vec![] + let ty_sub_vid = self.sub_unification_table_root_var(ty); + let inner = &mut *self.inner.borrow_mut(); + let mut type_variables = inner.type_variable_storage.with_log(&mut inner.undo_log); + inner + .opaque_type_storage + .iter_opaque_types() + .filter_map(|(key, hidden_ty)| { + let TyKind::Infer(InferTy::TyVar(hidden_vid)) = hidden_ty.ty.kind() else { + return None; + }; + (type_variables.sub_unification_table_root_var(hidden_vid) == ty_sub_vid).then( + || { + rustc_type_ir::AliasTy::new_from_args( + self.interner, + rustc_type_ir::Opaque { def_id: key.def_id }, + key.args, + ) + }, + ) + }) + .collect() } } diff --git a/crates/hir-ty/src/tests/regression/new_solver.rs b/crates/hir-ty/src/tests/regression/new_solver.rs index ecfc8968ab53..d64c7313da08 100644 --- a/crates/hir-ty/src/tests/regression/new_solver.rs +++ b/crates/hir-ty/src/tests/regression/new_solver.rs @@ -669,6 +669,40 @@ where ); } +#[test] +fn opaque_iterator_uses_blanket_into_iterator_impl() { + check_types( + r#" +//- minicore: iterator +struct Item; +impl Item { + fn method(&self) -> usize { + 0 + } +} + +struct Iter; +impl Iterator for Iter { + type Item = Item; + + fn next(&mut self) -> Option { + None + } +} + +fn iterator(recurse: bool) -> impl Iterator { + if recurse { + for item in iterator(false) { + item.method(); + //^^^^^^^^^^^^^ usize + } + } + Iter +} +"#, + ); +} + #[test] fn regression_16282() { check_infer(