@@ -230,7 +230,7 @@ where
230
230
B :: Data : Send ,
231
231
E : Unpin ,
232
232
B :: Error : Into < Box < dyn Error + Send + Sync > > ,
233
- E : Http2ClientConnExec < B , T > + ' static + Send + Sync + Unpin ,
233
+ E : Http2ClientConnExec < B , T > + Unpin ,
234
234
{
235
235
type Output = crate :: Result < ( ) > ;
236
236
@@ -457,3 +457,219 @@ where
457
457
}
458
458
}
459
459
}
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