Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/hir-ty/src/dyn_compatibility.rs | 24 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/regression/new_solver.rs | 56 |
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] |