Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/next_solver/mapping.rs7
-rw-r--r--crates/hir-ty/src/tests/traits.rs32
2 files changed, 39 insertions, 0 deletions
diff --git a/crates/hir-ty/src/next_solver/mapping.rs b/crates/hir-ty/src/next_solver/mapping.rs
index 4696cf479c..20cd8626f2 100644
--- a/crates/hir-ty/src/next_solver/mapping.rs
+++ b/crates/hir-ty/src/next_solver/mapping.rs
@@ -1148,6 +1148,13 @@ pub(crate) fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>)
}),
);
+ // Rust and chalk have slightly different
+ // representation for trait objects.
+ //
+ // Chalk uses `for<T0> for<'a> T0: Trait<'a>` while rustc
+ // uses `ExistentialPredicate`s, which do not have a self ty.
+ // We need to shift escaping bound vars by 1 to accommodate
+ // the newly introduced `for<T0>` binder.
let p = shift_vars(interner, p, 1);
let where_clause = match p.skip_binder() {
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 2e4346a869..9d72105624 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -4994,3 +4994,35 @@ fn main() {
"#]],
);
}
+
+#[test]
+fn trait_object_binders() {
+ check_infer(
+ r#"
+//- minicore: iterator, dispatch_from_dyn
+fn main() {
+ struct Box<T: ?Sized>(*const T);
+ impl<I: Iterator + ?Sized> Iterator for Box<I> {
+ type Item = I::Item;
+ fn next(&mut self) -> Option<I::Item> {
+ loop {}
+ }
+ }
+ let iter: Box<dyn Iterator<Item = &[u8]> + 'static> = loop {};
+ let _ = iter.into_iter();
+}"#,
+ expect![[r#"
+ 10..313 '{ ...r(); }': ()
+ 223..227 'iter': Box<dyn Iterator<Item = &'? [u8]> + 'static>
+ 273..280 'loop {}': !
+ 278..280 '{}': ()
+ 290..291 '_': Box<dyn Iterator<Item = &'? [u8]> + 'static>
+ 294..298 'iter': Box<dyn Iterator<Item = &'? [u8]> + 'static>
+ 294..310 'iter.i...iter()': Box<dyn Iterator<Item = &'? [u8]> + 'static>
+ 152..156 'self': &'? mut Box<I>
+ 177..208 '{ ... }': Option<Iterator::Item<I>>
+ 191..198 'loop {}': !
+ 196..198 '{}': ()
+ "#]],
+ );
+}