@@ -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,171 @@ 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 :: < _ , _ , http_body_util:: Empty < bytes:: Bytes > > ( LocalTokioExecutor , io) . await . unwrap ( ) ;
483
+
484
+ tokio:: task:: spawn_local ( async move {
485
+ conn. await . unwrap ( ) ;
486
+ } ) ;
487
+ }
488
+ }
489
+
490
+ #[ tokio:: test]
491
+ #[ ignore] // only compilation is checked
492
+ async fn not_send_not_sync_executor_of_not_send_futures ( ) {
493
+ #[ derive( Clone ) ]
494
+ struct LocalTokioExecutor {
495
+ _x : std:: marker:: PhantomData < std:: rc:: Rc < ( ) > >
496
+ }
497
+
498
+ impl < F > crate :: rt:: Executor < F > for LocalTokioExecutor
499
+ where
500
+ F : std:: future:: Future + ' static , // not requiring `Send`
501
+ {
502
+ fn execute ( & self , fut : F ) {
503
+ // This will spawn into the currently running `LocalSet`.
504
+ tokio:: task:: spawn_local ( fut) ;
505
+ }
506
+ }
507
+
508
+ #[ allow( unused) ]
509
+ async fn run ( io : impl crate :: rt:: Read + crate :: rt:: Write + Unpin + ' static ) {
510
+ let ( _sender, conn) = crate :: client:: conn:: http2:: handshake :: < _ , _ , http_body_util:: Empty < bytes:: Bytes > > ( LocalTokioExecutor { _x : Default :: default ( ) } , io) . await . unwrap ( ) ;
511
+
512
+ tokio:: task:: spawn_local ( async move {
513
+ conn. await . unwrap ( ) ;
514
+ } ) ;
515
+ }
516
+ }
517
+
518
+ #[ tokio:: test]
519
+ #[ ignore] // only compilation is checked
520
+ async fn send_not_sync_executor_of_not_send_futures ( ) {
521
+ #[ derive( Clone ) ]
522
+ struct LocalTokioExecutor {
523
+ _x : std:: marker:: PhantomData < std:: cell:: Cell < ( ) > >
524
+ }
525
+
526
+ impl < F > crate :: rt:: Executor < F > for LocalTokioExecutor
527
+ where
528
+ F : std:: future:: Future + ' static , // not requiring `Send`
529
+ {
530
+ fn execute ( & self , fut : F ) {
531
+ // This will spawn into the currently running `LocalSet`.
532
+ tokio:: task:: spawn_local ( fut) ;
533
+ }
534
+ }
535
+
536
+ #[ allow( unused) ]
537
+ async fn run ( io : impl crate :: rt:: Read + crate :: rt:: Write + Unpin + ' static ) {
538
+ let ( _sender, conn) = crate :: client:: conn:: http2:: handshake :: < _ , _ , http_body_util:: Empty < bytes:: Bytes > > ( LocalTokioExecutor { _x : Default :: default ( ) } , io) . await . unwrap ( ) ;
539
+
540
+ tokio:: task:: spawn_local ( async move {
541
+ conn. await . unwrap ( ) ;
542
+ } ) ;
543
+ }
544
+ }
545
+
546
+ #[ tokio:: test]
547
+ #[ ignore] // only compilation is checked
548
+ async fn send_sync_executor_of_send_futures ( ) {
549
+ #[ derive( Clone ) ]
550
+ struct TokioExecutor ;
551
+
552
+ impl < F > crate :: rt:: Executor < F > for TokioExecutor
553
+ where
554
+ F : std:: future:: Future + ' static + Send ,
555
+ F :: Output : Send + ' static ,
556
+ {
557
+ fn execute ( & self , fut : F ) {
558
+ tokio:: task:: spawn ( fut) ;
559
+ }
560
+ }
561
+
562
+ #[ allow( unused) ]
563
+ async fn run ( io : impl crate :: rt:: Read + crate :: rt:: Write + Send + Unpin + ' static ) {
564
+ let ( _sender, conn) = crate :: client:: conn:: http2:: handshake :: < _ , _ , http_body_util:: Empty < bytes:: Bytes > > ( TokioExecutor , io) . await . unwrap ( ) ;
565
+
566
+ tokio:: task:: spawn ( async move {
567
+ conn. await . unwrap ( ) ;
568
+ } ) ;
569
+ }
570
+ }
571
+
572
+ #[ tokio:: test]
573
+ #[ ignore] // only compilation is checked
574
+ async fn not_send_not_sync_executor_of_send_futures ( ) {
575
+ #[ derive( Clone ) ]
576
+ struct TokioExecutor { // !Send, !Sync
577
+ _x : std:: marker:: PhantomData < std:: rc:: Rc < ( ) > >
578
+ }
579
+
580
+ impl < F > crate :: rt:: Executor < F > for TokioExecutor
581
+ where
582
+ F : std:: future:: Future + ' static + Send ,
583
+ F :: Output : Send + ' static ,
584
+ {
585
+ fn execute ( & self , fut : F ) {
586
+ tokio:: task:: spawn ( fut) ;
587
+ }
588
+ }
589
+
590
+ #[ allow( unused) ]
591
+ async fn run ( io : impl crate :: rt:: Read + crate :: rt:: Write + Send + Unpin + ' static ) {
592
+ let ( _sender, conn) = crate :: client:: conn:: http2:: handshake :: < _ , _ , http_body_util:: Empty < bytes:: Bytes > > ( TokioExecutor { _x : Default :: default ( ) } , io) . await . unwrap ( ) ;
593
+
594
+ tokio:: task:: spawn_local ( async move { // can't use spawn here because when executor is !Send
595
+ conn. await . unwrap ( ) ;
596
+ } ) ;
597
+ }
598
+ }
599
+
600
+ #[ tokio:: test]
601
+ #[ ignore] // only compilation is checked
602
+ async fn send_not_sync_executor_of_send_futures ( ) {
603
+ #[ derive( Clone ) ]
604
+ struct TokioExecutor { // !Sync
605
+ _x : std:: marker:: PhantomData < std:: cell:: Cell < ( ) > >
606
+ }
607
+
608
+ impl < F > crate :: rt:: Executor < F > for TokioExecutor
609
+ where
610
+ F : std:: future:: Future + ' static + Send ,
611
+ F :: Output : Send + ' static ,
612
+ {
613
+ fn execute ( & self , fut : F ) {
614
+ tokio:: task:: spawn ( fut) ;
615
+ }
616
+ }
617
+
618
+ #[ allow( unused) ]
619
+ async fn run ( io : impl crate :: rt:: Read + crate :: rt:: Write + Send + Unpin + ' static ) {
620
+ let ( _sender, conn) = crate :: client:: conn:: http2:: handshake :: < _ , _ , http_body_util:: Empty < bytes:: Bytes > > ( TokioExecutor { _x : Default :: default ( ) } , io) . await . unwrap ( ) ;
621
+
622
+ tokio:: task:: spawn_local ( async move { // can't use spawn here because when executor is !Send
623
+ conn. await . unwrap ( ) ;
624
+ } ) ;
625
+ }
626
+ }
627
+ }
0 commit comments