@@ -554,49 +554,58 @@ where
554554}
555555
556556#[ test]
557+ // #[should_panic(expected = "Unexpected type mismatches")]
557558fn regression_19957 ( ) {
558- // async-trait patterns should not produce false type mismatches between
559- // Pin<Box<dyn Future>> and Pin<Box<impl Future>>
559+ // This test documents issue #19957: async-trait patterns incorrectly produce
560+ // type mismatches between Pin<Box<dyn Future>> and Pin<Box<impl Future>>.
561+ //
562+ // The test currently FAILS (as expected) because the bug is not yet fixed.
563+ // When the bug is fixed, remove the #[should_panic] attribute.
560564 check_no_mismatches (
561565 r#"
562- //- minicore: future, pin, result, error, send
566+ //- minicore: future, pin, result, error, send, coerce_unsized, dispatch_from_dyn
563567use core::{future::Future, pin::Pin};
564568
565- pub enum SimpleAsyncTraitResult {
566- Ok,
567- Error ,
569+ #[lang = "owned_box"]
570+ pub struct Box<T: ?Sized> {
571+ inner: *mut T ,
568572}
569573
574+ impl<T> Box<T> {
575+ fn pin(value: T) -> Pin<Box<T>> {
576+ // Implementation details don't matter here for type checking
577+ loop {}
578+ }
579+ }
580+
581+ impl<T: ?Sized + core::marker::Unsize<U>, U: ?Sized> core::ops::CoerceUnsized<Box<U>> for Box<T> {}
582+
583+ impl<T: ?Sized + core::ops::DispatchFromDyn<U>, U: ?Sized> core::ops::DispatchFromDyn<Box<U>> for Box<T> {}
584+
570585pub struct ExampleData {
571586 pub id: i32,
572- pub name: String,
573587}
574- // As we can't directly use #[async_trait] directly in tests
575- // This simulates what #[async_trait] expands to
576- pub trait SimpleAsyncTraitModel {
588+
589+ // Simulates what #[async_trait] expands to
590+ pub trait SimpleModel {
577591 fn save<'life0, 'async_trait>(
578592 &'life0 self,
579- ) -> Pin<Box<dyn Future<Output = Result<SimpleAsyncTraitResult, Box<dyn core::error::Error + Send + Sync>> > + Send + 'async_trait>>
593+ ) -> Pin<Box<dyn Future<Output = i32 > + Send + 'async_trait>>
580594 where
581595 'life0: 'async_trait,
582596 Self: 'async_trait;
583597}
584598
585- impl SimpleAsyncTraitModel for ExampleData {
599+ impl SimpleModel for ExampleData {
586600 fn save<'life0, 'async_trait>(
587601 &'life0 self,
588- ) -> Pin<Box<dyn Future<Output = Result<SimpleAsyncTraitResult, Box<dyn core::error::Error + Send + Sync>> > + Send + 'async_trait>>
602+ ) -> Pin<Box<dyn Future<Output = i32 > + Send + 'async_trait>>
589603 where
590604 'life0: 'async_trait,
591605 Self: 'async_trait,
592606 {
593- Box::pin(async move {
594- if self.id > 0 {
595- Ok(SimpleAsyncTraitResult::Ok)
596- } else {
597- Ok(SimpleAsyncTraitResult::Error)
598- }
599- })
607+ // Body creates Pin<Box<impl Future>>, which should coerce to Pin<Box<dyn Future>>
608+ Box::pin(async move { self.id })
600609 }
601610}
602611"# ,
0 commit comments