Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21069 from Aditya-PS-05/feat/add-regression-test-19957
feat: add test for async-trait type mismatch
Shoyu Vanilla (Flint) 5 months ago
parent b342c20 · parent f39579c · commit b533f95
-rw-r--r--crates/hir-ty/src/tests/regression/new_solver.rs55
-rw-r--r--crates/test-utils/src/minicore.rs6
2 files changed, 61 insertions, 0 deletions
diff --git a/crates/hir-ty/src/tests/regression/new_solver.rs b/crates/hir-ty/src/tests/regression/new_solver.rs
index 933a9a5c35..18509c5284 100644
--- a/crates/hir-ty/src/tests/regression/new_solver.rs
+++ b/crates/hir-ty/src/tests/regression/new_solver.rs
@@ -552,3 +552,58 @@ where
"#]],
);
}
+
+#[test]
+fn regression_19957() {
+ // This test documents issue #19957: async-trait patterns incorrectly produce
+ // type mismatches between Pin<Box<dyn Future>> and Pin<Box<impl Future>>.
+ check_no_mismatches(
+ r#"
+//- minicore: future, pin, result, error, send, coerce_unsized, dispatch_from_dyn
+use core::{future::Future, pin::Pin};
+
+#[lang = "owned_box"]
+pub struct Box<T: ?Sized> {
+ inner: *mut T,
+}
+
+impl<T> Box<T> {
+ fn pin(value: T) -> Pin<Box<T>> {
+ // Implementation details don't matter here for type checking
+ loop {}
+ }
+}
+
+impl<T: ?Sized + core::marker::Unsize<U>, U: ?Sized> core::ops::CoerceUnsized<Box<U>> for Box<T> {}
+
+impl<T: ?Sized + core::ops::DispatchFromDyn<U>, U: ?Sized> core::ops::DispatchFromDyn<Box<U>> for Box<T> {}
+
+pub struct ExampleData {
+ pub id: i32,
+}
+
+// Simulates what #[async_trait] expands to
+pub trait SimpleModel {
+ fn save<'life0, 'async_trait>(
+ &'life0 self,
+ ) -> Pin<Box<dyn Future<Output = i32> + Send + 'async_trait>>
+ where
+ 'life0: 'async_trait,
+ Self: 'async_trait;
+}
+
+impl SimpleModel for ExampleData {
+ fn save<'life0, 'async_trait>(
+ &'life0 self,
+ ) -> Pin<Box<dyn Future<Output = i32> + Send + 'async_trait>>
+ where
+ 'life0: 'async_trait,
+ Self: 'async_trait,
+ {
+ // Body creates Pin<Box<impl Future>>, which should coerce to Pin<Box<dyn Future>>
+ Box::pin(async move { self.id })
+ }
+}
+"#,
+ );
+}
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index d5905afc38..679fe420b0 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -1518,6 +1518,12 @@ pub mod pin {
{
}
// endregion:dispatch_from_dyn
+ // region:coerce_unsized
+ impl<Ptr, U> crate::ops::CoerceUnsized<Pin<U>> for Pin<Ptr> where
+ Ptr: crate::ops::CoerceUnsized<U>
+ {
+ }
+ // endregion:coerce_unsized
}
// endregion:pin