@@ -16,7 +16,7 @@ use rustc_hir::def::Res;
16
16
use rustc_hir:: definitions:: DefPathData ;
17
17
use rustc_session:: errors:: report_lit_error;
18
18
use rustc_span:: source_map:: { respan, DesugaringKind , Span , Spanned } ;
19
- use rustc_span:: symbol:: { sym, Ident } ;
19
+ use rustc_span:: symbol:: { kw , sym, Ident } ;
20
20
use rustc_span:: DUMMY_SP ;
21
21
use thin_vec:: thin_vec;
22
22
@@ -594,14 +594,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
594
594
) -> hir:: ExprKind < ' hir > {
595
595
let output = ret_ty. unwrap_or_else ( || hir:: FnRetTy :: DefaultReturn ( self . lower_span ( span) ) ) ;
596
596
597
- // Resume argument type: `ResumeTy`
598
- let unstable_span =
599
- self . mark_span_with_reason ( DesugaringKind :: Async , span, self . allow_gen_future . clone ( ) ) ;
600
- let resume_ty = hir:: QPath :: LangItem ( hir:: LangItem :: ResumeTy , unstable_span, None ) ;
597
+ // Resume argument type, which should be `&mut Context<'_>`.
598
+ // NOTE: Using the `'static` lifetime here is technically cheating.
599
+ // The `Future::poll` argument really is `&'a mut Context<'b>`, but we cannot
600
+ // express the fact that we are not storing it across yield-points yet,
601
+ // and we would thus run into lifetime errors.
602
+ // See <https://github.com/rust-lang/rust/issues/68923>.
603
+ // Our lowering makes sure we are not mis-using the `_task_context` input type
604
+ // in the sense that we are indeed not using it across yield points. We
605
+ // get a fresh `&mut Context` for each resume / call of `Future::poll`.
606
+ // This "cheating" was previously done with a `ResumeTy` that contained a raw
607
+ // pointer, and a `get_context` accessor that pulled the `Context` lifetimes
608
+ // out of thin air.
609
+ let context_lifetime_ident = Ident :: with_dummy_span ( kw:: StaticLifetime ) ;
610
+ let context_lifetime = self . arena . alloc ( hir:: Lifetime {
611
+ hir_id : self . next_id ( ) ,
612
+ ident : context_lifetime_ident,
613
+ res : hir:: LifetimeName :: Static ,
614
+ } ) ;
615
+ let context_path =
616
+ hir:: QPath :: LangItem ( hir:: LangItem :: Context , self . lower_span ( span) , None ) ;
617
+ let context_ty = hir:: MutTy {
618
+ ty : self . arena . alloc ( hir:: Ty {
619
+ hir_id : self . next_id ( ) ,
620
+ kind : hir:: TyKind :: Path ( context_path) ,
621
+ span : self . lower_span ( span) ,
622
+ } ) ,
623
+ mutbl : hir:: Mutability :: Mut ,
624
+ } ;
601
625
let input_ty = hir:: Ty {
602
626
hir_id : self . next_id ( ) ,
603
- kind : hir:: TyKind :: Path ( resume_ty ) ,
604
- span : unstable_span ,
627
+ kind : hir:: TyKind :: Rptr ( context_lifetime , context_ty ) ,
628
+ span : self . lower_span ( span ) ,
605
629
} ;
606
630
607
631
// The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`.
@@ -659,12 +683,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
659
683
. map_or ( false , |attrs| attrs. into_iter ( ) . any ( |attr| attr. has_name ( sym:: track_caller) ) ) ;
660
684
661
685
let hir_id = self . lower_node_id ( closure_node_id) ;
686
+ let unstable_span =
687
+ self . mark_span_with_reason ( DesugaringKind :: Async , span, self . allow_gen_future . clone ( ) ) ;
662
688
if track_caller {
663
- let unstable_span = self . mark_span_with_reason (
664
- DesugaringKind :: Async ,
665
- span,
666
- self . allow_gen_future . clone ( ) ,
667
- ) ;
668
689
self . lower_attrs (
669
690
hir_id,
670
691
& [ Attribute {
@@ -711,7 +732,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
711
732
/// mut __awaitee => loop {
712
733
/// match unsafe { ::std::future::Future::poll(
713
734
/// <::std::pin::Pin>::new_unchecked(&mut __awaitee),
714
- /// ::std::future::get_context( task_context) ,
735
+ /// task_context,
715
736
/// ) } {
716
737
/// ::std::task::Poll::Ready(result) => break result,
717
738
/// ::std::task::Poll::Pending => {}
@@ -752,7 +773,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
752
773
// unsafe {
753
774
// ::std::future::Future::poll(
754
775
// ::std::pin::Pin::new_unchecked(&mut __awaitee),
755
- // ::std::future::get_context( task_context) ,
776
+ // task_context,
756
777
// )
757
778
// }
758
779
let poll_expr = {
@@ -770,16 +791,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
770
791
arena_vec ! [ self ; ref_mut_awaitee] ,
771
792
Some ( expr_hir_id) ,
772
793
) ;
773
- let get_context = self . expr_call_lang_item_fn_mut (
774
- gen_future_span,
775
- hir:: LangItem :: GetContext ,
776
- arena_vec ! [ self ; task_context] ,
777
- Some ( expr_hir_id) ,
778
- ) ;
779
794
let call = self . expr_call_lang_item_fn (
780
795
span,
781
796
hir:: LangItem :: FuturePoll ,
782
- arena_vec ! [ self ; new_unchecked, get_context ] ,
797
+ arena_vec ! [ self ; new_unchecked, task_context ] ,
783
798
Some ( expr_hir_id) ,
784
799
) ;
785
800
self . arena . alloc ( self . expr_unsafe ( call) )
0 commit comments