Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/dyn_compatibility.rs24
-rw-r--r--crates/hir-ty/src/tests/regression/new_solver.rs56
2 files changed, 70 insertions, 10 deletions
diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs
index 506c4abc83..64b15eb017 100644
--- a/crates/hir-ty/src/dyn_compatibility.rs
+++ b/crates/hir-ty/src/dyn_compatibility.rs
@@ -427,9 +427,14 @@ fn receiver_is_dispatchable<'db>(
};
let meta_sized_did = lang_items.MetaSized;
- let Some(meta_sized_did) = meta_sized_did else {
- return false;
- };
+
+ // TODO: This is for supporting dyn compatibility for toolchains doesn't contain `MetaSized`
+ // trait. Uncomment and short circuit here once `MINIMUM_SUPPORTED_TOOLCHAIN_VERSION`
+ // become > 1.88.0
+ //
+ // let Some(meta_sized_did) = meta_sized_did else {
+ // return false;
+ // };
// Type `U`
// FIXME: That seems problematic to fake a generic param like that?
@@ -450,17 +455,16 @@ fn receiver_is_dispatchable<'db>(
});
let trait_predicate = TraitRef::new_from_args(interner, trait_.into(), args);
- let meta_sized_predicate =
- TraitRef::new(interner, meta_sized_did.into(), [unsized_self_ty]);
+ let meta_sized_predicate = meta_sized_did
+ .map(|did| TraitRef::new(interner, did.into(), [unsized_self_ty]).upcast(interner));
ParamEnv {
clauses: Clauses::new_from_iter(
interner,
- generic_predicates.iter_identity_copied().chain([
- unsize_predicate.upcast(interner),
- trait_predicate.upcast(interner),
- meta_sized_predicate.upcast(interner),
- ]),
+ generic_predicates
+ .iter_identity_copied()
+ .chain([unsize_predicate.upcast(interner), trait_predicate.upcast(interner)])
+ .chain(meta_sized_predicate),
),
}
};
diff --git a/crates/hir-ty/src/tests/regression/new_solver.rs b/crates/hir-ty/src/tests/regression/new_solver.rs
index 5c1f85cb2a..e11cc85e7f 100644
--- a/crates/hir-ty/src/tests/regression/new_solver.rs
+++ b/crates/hir-ty/src/tests/regression/new_solver.rs
@@ -230,6 +230,62 @@ fn main() {
debug(&1);
}"#,
);
+
+ // toolchains <= 1.88.0, before sized-hierarchy.
+ check_no_mismatches(
+ r#"
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "unsize"]
+pub trait Unsize<T: ?Sized> {}
+
+#[lang = "coerce_unsized"]
+pub trait CoerceUnsized<T: ?Sized> {}
+
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
+
+impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
+
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
+
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
+
+impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
+
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
+
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
+
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
+
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
+
+#[lang = "dispatch_from_dyn"]
+pub trait DispatchFromDyn<T> {}
+
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
+
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
+
+impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
+
+impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
+
+trait Foo {
+ fn bar(&self) -> u32 {
+ 0xCAFE
+ }
+}
+
+fn debug(_: &dyn Foo) {}
+
+impl Foo for i32 {}
+
+fn main() {
+ debug(&1);
+}"#,
+ );
}
#[test]