@@ -113,6 +113,33 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor {
113113 }
114114}
115115
116+ struct PinArgVisitor < ' tcx > {
117+ ref_gen_ty : Ty < ' tcx > ,
118+ }
119+
120+ impl < ' tcx > MutVisitor < ' tcx > for PinArgVisitor < ' tcx > {
121+ fn visit_local ( & mut self ,
122+ local : & mut Local ,
123+ _: PlaceContext < ' tcx > ,
124+ _: Location ) {
125+ assert_ne ! ( * local, self_arg( ) ) ;
126+ }
127+
128+ fn visit_place ( & mut self ,
129+ place : & mut Place < ' tcx > ,
130+ context : PlaceContext < ' tcx > ,
131+ location : Location ) {
132+ if * place == Place :: Local ( self_arg ( ) ) {
133+ * place = Place :: Projection ( Box :: new ( Projection {
134+ base : place. clone ( ) ,
135+ elem : ProjectionElem :: Field ( Field :: new ( 0 ) , self . ref_gen_ty ) ,
136+ } ) ) ;
137+ } else {
138+ self . super_place ( place, context, location) ;
139+ }
140+ }
141+ }
142+
116143fn self_arg ( ) -> Local {
117144 Local :: new ( 1 )
118145}
@@ -286,6 +313,23 @@ fn make_generator_state_argument_indirect<'a, 'tcx>(
286313 DerefArgVisitor . visit_mir ( mir) ;
287314}
288315
316+ fn make_generator_state_argument_pinned < ' a , ' tcx > (
317+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
318+ mir : & mut Mir < ' tcx > ) {
319+ let ref_gen_ty = mir. local_decls . raw [ 1 ] . ty ;
320+
321+ let pin_did = tcx. lang_items ( ) . pin_type ( ) . unwrap ( ) ;
322+ let pin_adt_ref = tcx. adt_def ( pin_did) ;
323+ let substs = tcx. intern_substs ( & [ ref_gen_ty. into ( ) ] ) ;
324+ let pin_ref_gen_ty = tcx. mk_adt ( pin_adt_ref, substs) ;
325+
326+ // Replace the by ref generator argument
327+ mir. local_decls . raw [ 1 ] . ty = pin_ref_gen_ty;
328+
329+ // Add the Pin field access to accesses of the generator state
330+ PinArgVisitor { ref_gen_ty } . visit_mir ( mir) ;
331+ }
332+
289333fn replace_result_variable < ' tcx > (
290334 ret_ty : Ty < ' tcx > ,
291335 mir : & mut Mir < ' tcx > ,
@@ -741,6 +785,7 @@ fn create_generator_resume_function<'a, 'tcx>(
741785 insert_switch ( tcx, mir, cases, & transform, TerminatorKind :: Unreachable ) ;
742786
743787 make_generator_state_argument_indirect ( tcx, def_id, mir) ;
788+ make_generator_state_argument_pinned ( tcx, mir) ;
744789
745790 no_landing_pads ( tcx, mir) ;
746791
0 commit comments