@@ -230,7 +230,7 @@ where
230230 B :: Data : Send ,
231231 E : Unpin ,
232232 B :: Error : Into < Box < dyn Error + Send + Sync > > ,
233- E : Http2ClientConnExec < B , T > + ' static + Send + Sync + Unpin ,
233+ E : Http2ClientConnExec < B , T > + Unpin ,
234234{
235235 type Output = crate :: Result < ( ) > ;
236236
@@ -457,3 +457,219 @@ where
457457 }
458458 }
459459}
460+
461+ #[ cfg( test) ]
462+ mod tests {
463+
464+ #[ tokio:: test]
465+ #[ ignore] // only compilation is checked
466+ async fn send_sync_executor_of_non_send_futures ( ) {
467+ #[ derive( Clone ) ]
468+ struct LocalTokioExecutor ;
469+
470+ impl < F > crate :: rt:: Executor < F > for LocalTokioExecutor
471+ where
472+ F : std:: future:: Future + ' static , // not requiring `Send`
473+ {
474+ fn execute ( & self , fut : F ) {
475+ // This will spawn into the currently running `LocalSet`.
476+ tokio:: task:: spawn_local ( fut) ;
477+ }
478+ }
479+
480+ #[ allow( unused) ]
481+ async fn run ( io : impl crate :: rt:: Read + crate :: rt:: Write + Unpin + ' static ) {
482+ let ( _sender, conn) = crate :: client:: conn:: http2:: handshake :: <
483+ _ ,
484+ _ ,
485+ http_body_util:: Empty < bytes:: Bytes > ,
486+ > ( LocalTokioExecutor , io)
487+ . await
488+ . unwrap ( ) ;
489+
490+ tokio:: task:: spawn_local ( async move {
491+ conn. await . unwrap ( ) ;
492+ } ) ;
493+ }
494+ }
495+
496+ #[ tokio:: test]
497+ #[ ignore] // only compilation is checked
498+ async fn not_send_not_sync_executor_of_not_send_futures ( ) {
499+ #[ derive( Clone ) ]
500+ struct LocalTokioExecutor {
501+ _x : std:: marker:: PhantomData < std:: rc:: Rc < ( ) > > ,
502+ }
503+
504+ impl < F > crate :: rt:: Executor < F > for LocalTokioExecutor
505+ where
506+ F : std:: future:: Future + ' static , // not requiring `Send`
507+ {
508+ fn execute ( & self , fut : F ) {
509+ // This will spawn into the currently running `LocalSet`.
510+ tokio:: task:: spawn_local ( fut) ;
511+ }
512+ }
513+
514+ #[ allow( unused) ]
515+ async fn run ( io : impl crate :: rt:: Read + crate :: rt:: Write + Unpin + ' static ) {
516+ let ( _sender, conn) =
517+ crate :: client:: conn:: http2:: handshake :: < _ , _ , http_body_util:: Empty < bytes:: Bytes > > (
518+ LocalTokioExecutor {
519+ _x : Default :: default ( ) ,
520+ } ,
521+ io,
522+ )
523+ . await
524+ . unwrap ( ) ;
525+
526+ tokio:: task:: spawn_local ( async move {
527+ conn. await . unwrap ( ) ;
528+ } ) ;
529+ }
530+ }
531+
532+ #[ tokio:: test]
533+ #[ ignore] // only compilation is checked
534+ async fn send_not_sync_executor_of_not_send_futures ( ) {
535+ #[ derive( Clone ) ]
536+ struct LocalTokioExecutor {
537+ _x : std:: marker:: PhantomData < std:: cell:: Cell < ( ) > > ,
538+ }
539+
540+ impl < F > crate :: rt:: Executor < F > for LocalTokioExecutor
541+ where
542+ F : std:: future:: Future + ' static , // not requiring `Send`
543+ {
544+ fn execute ( & self , fut : F ) {
545+ // This will spawn into the currently running `LocalSet`.
546+ tokio:: task:: spawn_local ( fut) ;
547+ }
548+ }
549+
550+ #[ allow( unused) ]
551+ async fn run ( io : impl crate :: rt:: Read + crate :: rt:: Write + Unpin + ' static ) {
552+ let ( _sender, conn) =
553+ crate :: client:: conn:: http2:: handshake :: < _ , _ , http_body_util:: Empty < bytes:: Bytes > > (
554+ LocalTokioExecutor {
555+ _x : Default :: default ( ) ,
556+ } ,
557+ io,
558+ )
559+ . await
560+ . unwrap ( ) ;
561+
562+ tokio:: task:: spawn_local ( async move {
563+ conn. await . unwrap ( ) ;
564+ } ) ;
565+ }
566+ }
567+
568+ #[ tokio:: test]
569+ #[ ignore] // only compilation is checked
570+ async fn send_sync_executor_of_send_futures ( ) {
571+ #[ derive( Clone ) ]
572+ struct TokioExecutor ;
573+
574+ impl < F > crate :: rt:: Executor < F > for TokioExecutor
575+ where
576+ F : std:: future:: Future + ' static + Send ,
577+ F :: Output : Send + ' static ,
578+ {
579+ fn execute ( & self , fut : F ) {
580+ tokio:: task:: spawn ( fut) ;
581+ }
582+ }
583+
584+ #[ allow( unused) ]
585+ async fn run ( io : impl crate :: rt:: Read + crate :: rt:: Write + Send + Unpin + ' static ) {
586+ let ( _sender, conn) = crate :: client:: conn:: http2:: handshake :: <
587+ _ ,
588+ _ ,
589+ http_body_util:: Empty < bytes:: Bytes > ,
590+ > ( TokioExecutor , io)
591+ . await
592+ . unwrap ( ) ;
593+
594+ tokio:: task:: spawn ( async move {
595+ conn. await . unwrap ( ) ;
596+ } ) ;
597+ }
598+ }
599+
600+ #[ tokio:: test]
601+ #[ ignore] // only compilation is checked
602+ async fn not_send_not_sync_executor_of_send_futures ( ) {
603+ #[ derive( Clone ) ]
604+ struct TokioExecutor {
605+ // !Send, !Sync
606+ _x : std:: marker:: PhantomData < std:: rc:: Rc < ( ) > > ,
607+ }
608+
609+ impl < F > crate :: rt:: Executor < F > for TokioExecutor
610+ where
611+ F : std:: future:: Future + ' static + Send ,
612+ F :: Output : Send + ' static ,
613+ {
614+ fn execute ( & self , fut : F ) {
615+ tokio:: task:: spawn ( fut) ;
616+ }
617+ }
618+
619+ #[ allow( unused) ]
620+ async fn run ( io : impl crate :: rt:: Read + crate :: rt:: Write + Send + Unpin + ' static ) {
621+ let ( _sender, conn) =
622+ crate :: client:: conn:: http2:: handshake :: < _ , _ , http_body_util:: Empty < bytes:: Bytes > > (
623+ TokioExecutor {
624+ _x : Default :: default ( ) ,
625+ } ,
626+ io,
627+ )
628+ . await
629+ . unwrap ( ) ;
630+
631+ tokio:: task:: spawn_local ( async move {
632+ // can't use spawn here because when executor is !Send
633+ conn. await . unwrap ( ) ;
634+ } ) ;
635+ }
636+ }
637+
638+ #[ tokio:: test]
639+ #[ ignore] // only compilation is checked
640+ async fn send_not_sync_executor_of_send_futures ( ) {
641+ #[ derive( Clone ) ]
642+ struct TokioExecutor {
643+ // !Sync
644+ _x : std:: marker:: PhantomData < std:: cell:: Cell < ( ) > > ,
645+ }
646+
647+ impl < F > crate :: rt:: Executor < F > for TokioExecutor
648+ where
649+ F : std:: future:: Future + ' static + Send ,
650+ F :: Output : Send + ' static ,
651+ {
652+ fn execute ( & self , fut : F ) {
653+ tokio:: task:: spawn ( fut) ;
654+ }
655+ }
656+
657+ #[ allow( unused) ]
658+ async fn run ( io : impl crate :: rt:: Read + crate :: rt:: Write + Send + Unpin + ' static ) {
659+ let ( _sender, conn) =
660+ crate :: client:: conn:: http2:: handshake :: < _ , _ , http_body_util:: Empty < bytes:: Bytes > > (
661+ TokioExecutor {
662+ _x : Default :: default ( ) ,
663+ } ,
664+ io,
665+ )
666+ . await
667+ . unwrap ( ) ;
668+
669+ tokio:: task:: spawn_local ( async move {
670+ // can't use spawn here because when executor is !Send
671+ conn. await . unwrap ( ) ;
672+ } ) ;
673+ }
674+ }
675+ }
0 commit comments