@@ -16,7 +16,7 @@ use rustc_hir::def::Res;
1616use rustc_hir:: definitions:: DefPathData ;
1717use rustc_session:: errors:: report_lit_error;
1818use rustc_span:: source_map:: { respan, DesugaringKind , Span , Spanned } ;
19- use rustc_span:: symbol:: { sym, Ident } ;
19+ use rustc_span:: symbol:: { kw , sym, Ident } ;
2020use rustc_span:: DUMMY_SP ;
2121use thin_vec:: thin_vec;
2222
@@ -592,14 +592,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
592592 ) -> hir:: ExprKind < ' hir > {
593593 let output = ret_ty. unwrap_or_else ( || hir:: FnRetTy :: DefaultReturn ( self . lower_span ( span) ) ) ;
594594
595- // Resume argument type: `ResumeTy`
596- let unstable_span =
597- self . mark_span_with_reason ( DesugaringKind :: Async , span, self . allow_gen_future . clone ( ) ) ;
598- let resume_ty = hir:: QPath :: LangItem ( hir:: LangItem :: ResumeTy , unstable_span, None ) ;
595+ // Resume argument type, which should be `&mut Context<'_>`.
596+ // NOTE: Using the `'static` lifetime here is technically cheating.
597+ // The `Future::poll` argument really is `&'a mut Context<'b>`, but we cannot
598+ // express the fact that we are not storing it across yield-points yet,
599+ // and we would thus run into lifetime errors.
600+ // See <https://github.com/rust-lang/rust/issues/68923>.
601+ // Our lowering makes sure we are not mis-using the `_task_context` input type
602+ // in the sense that we are indeed not using it across yield points. We
603+ // get a fresh `&mut Context` for each resume / call of `Future::poll`.
604+ // This "cheating" was previously done with a `ResumeTy` that contained a raw
605+ // pointer, and a `get_context` accessor that pulled the `Context` lifetimes
606+ // out of thin air.
607+ let context_lifetime_ident = Ident :: with_dummy_span ( kw:: StaticLifetime ) ;
608+ let context_lifetime = self . arena . alloc ( hir:: Lifetime {
609+ hir_id : self . next_id ( ) ,
610+ ident : context_lifetime_ident,
611+ res : hir:: LifetimeName :: Static ,
612+ } ) ;
613+ let context_path =
614+ hir:: QPath :: LangItem ( hir:: LangItem :: Context , self . lower_span ( span) , None ) ;
615+ let context_ty = hir:: MutTy {
616+ ty : self . arena . alloc ( hir:: Ty {
617+ hir_id : self . next_id ( ) ,
618+ kind : hir:: TyKind :: Path ( context_path) ,
619+ span : self . lower_span ( span) ,
620+ } ) ,
621+ mutbl : hir:: Mutability :: Mut ,
622+ } ;
599623 let input_ty = hir:: Ty {
600624 hir_id : self . next_id ( ) ,
601- kind : hir:: TyKind :: Path ( resume_ty ) ,
602- span : unstable_span ,
625+ kind : hir:: TyKind :: Rptr ( context_lifetime , context_ty ) ,
626+ span : self . lower_span ( span ) ,
603627 } ;
604628
605629 // The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`.
@@ -710,7 +734,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
710734 /// mut __awaitee => loop {
711735 /// match unsafe { ::std::future::Future::poll(
712736 /// <::std::pin::Pin>::new_unchecked(&mut __awaitee),
713- /// ::std::future::get_context( task_context) ,
737+ /// task_context,
714738 /// ) } {
715739 /// ::std::task::Poll::Ready(result) => break result,
716740 /// ::std::task::Poll::Pending => {}
@@ -751,7 +775,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
751775 // unsafe {
752776 // ::std::future::Future::poll(
753777 // ::std::pin::Pin::new_unchecked(&mut __awaitee),
754- // ::std::future::get_context( task_context) ,
778+ // task_context,
755779 // )
756780 // }
757781 let poll_expr = {
@@ -769,16 +793,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
769793 arena_vec ! [ self ; ref_mut_awaitee] ,
770794 Some ( expr_hir_id) ,
771795 ) ;
772- let get_context = self . expr_call_lang_item_fn_mut (
773- gen_future_span,
774- hir:: LangItem :: GetContext ,
775- arena_vec ! [ self ; task_context] ,
776- Some ( expr_hir_id) ,
777- ) ;
778796 let call = self . expr_call_lang_item_fn (
779797 span,
780798 hir:: LangItem :: FuturePoll ,
781- arena_vec ! [ self ; new_unchecked, get_context ] ,
799+ arena_vec ! [ self ; new_unchecked, task_context ] ,
782800 Some ( expr_hir_id) ,
783801 ) ;
784802 self . arena . alloc ( self . expr_unsafe ( call) )
0 commit comments