@@ -358,20 +358,41 @@ impl<'tcx> GotocCtx<'tcx> {
358
358
// `Generator::resume(...) -> GeneratorState` function in case we
359
359
// have an ordinary generator, or the `Future::poll(...) -> Poll`
360
360
// function in case this is a special generator backing an async construct.
361
- let ret_ty = if self . tcx . generator_is_async ( * did) {
362
- let state_did = self . tcx . require_lang_item ( LangItem :: Poll , None ) ;
363
- let state_adt_ref = self . tcx . adt_def ( state_did) ;
364
- let state_substs = self . tcx . intern_substs ( & [ sig. return_ty . into ( ) ] ) ;
365
- self . tcx . mk_adt ( state_adt_ref, state_substs)
361
+ let tcx = self . tcx ;
362
+ let ( resume_ty, ret_ty) = if tcx. generator_is_async ( * did) {
363
+ // The signature should be `Future::poll(_, &mut Context<'_>) -> Poll<Output>`
364
+ let poll_did = tcx. require_lang_item ( LangItem :: Poll , None ) ;
365
+ let poll_adt_ref = tcx. adt_def ( poll_did) ;
366
+ let poll_substs = tcx. intern_substs ( & [ sig. return_ty . into ( ) ] ) ;
367
+ let ret_ty = tcx. mk_adt ( poll_adt_ref, poll_substs) ;
368
+
369
+ // We have to replace the `ResumeTy` that is used for type and borrow checking
370
+ // with `&mut Context<'_>` which is used in codegen.
371
+ #[ cfg( debug_assertions) ]
372
+ {
373
+ if let ty:: Adt ( resume_ty_adt, _) = sig. resume_ty . kind ( ) {
374
+ let expected_adt = tcx. adt_def ( tcx. require_lang_item ( LangItem :: ResumeTy , None ) ) ;
375
+ assert_eq ! ( * resume_ty_adt, expected_adt) ;
376
+ } else {
377
+ panic ! ( "expected `ResumeTy`, found `{:?}`" , sig. resume_ty) ;
378
+ } ;
379
+ }
380
+ let context_mut_ref = tcx. mk_task_context ( ) ;
381
+
382
+ ( context_mut_ref, ret_ty)
366
383
} else {
367
- let state_did = self . tcx . require_lang_item ( LangItem :: GeneratorState , None ) ;
368
- let state_adt_ref = self . tcx . adt_def ( state_did) ;
369
- let state_substs = self . tcx . intern_substs ( & [ sig. yield_ty . into ( ) , sig. return_ty . into ( ) ] ) ;
370
- self . tcx . mk_adt ( state_adt_ref, state_substs)
384
+ // The signature should be `Generator::resume(_, Resume) -> GeneratorState<Yield, Return>`
385
+ let state_did = tcx. require_lang_item ( LangItem :: GeneratorState , None ) ;
386
+ let state_adt_ref = tcx. adt_def ( state_did) ;
387
+ let state_substs = tcx. intern_substs ( & [ sig. yield_ty . into ( ) , sig. return_ty . into ( ) ] ) ;
388
+ let ret_ty = tcx. mk_adt ( state_adt_ref, state_substs) ;
389
+
390
+ ( sig. resume_ty , ret_ty)
371
391
} ;
392
+
372
393
ty:: Binder :: bind_with_vars (
373
- self . tcx . mk_fn_sig (
374
- [ env_ty, sig . resume_ty ] . iter ( ) ,
394
+ tcx. mk_fn_sig (
395
+ [ env_ty, resume_ty] . iter ( ) ,
375
396
& ret_ty,
376
397
false ,
377
398
Unsafety :: Normal ,
@@ -813,7 +834,7 @@ impl<'tcx> GotocCtx<'tcx> {
813
834
)
814
835
}
815
836
}
816
- ty:: Projection ( _ ) | ty :: Opaque ( _ , _ ) => {
837
+ ty:: Alias ( .. ) => {
817
838
unreachable ! ( "Type should've been normalized already" )
818
839
}
819
840
@@ -1226,7 +1247,7 @@ impl<'tcx> GotocCtx<'tcx> {
1226
1247
ty:: Dynamic ( ..) | ty:: Slice ( _) | ty:: Str => {
1227
1248
unreachable ! ( "Should have generated a fat pointer" )
1228
1249
}
1229
- ty:: Projection ( _ ) | ty :: Opaque ( ..) => {
1250
+ ty:: Alias ( ..) => {
1230
1251
unreachable ! ( "Should have been removed by normalization" )
1231
1252
}
1232
1253
0 commit comments