@@ -95,8 +95,7 @@ pub struct LoweringContext<'a> {
9595
9696 modules : BTreeMap < NodeId , hir:: ModuleItems > ,
9797
98- is_generator : bool ,
99- is_async_body : bool ,
98+ generator_kind : Option < hir:: GeneratorKind > ,
10099
101100 /// Used to get the current `fn`'s def span to point to when using `await`
102101 /// outside of an `async fn`.
@@ -264,8 +263,7 @@ pub fn lower_crate(
264263 current_hir_id_owner : vec ! [ ( CRATE_DEF_INDEX , 0 ) ] ,
265264 item_local_id_counters : Default :: default ( ) ,
266265 node_id_to_hir_id : IndexVec :: new ( ) ,
267- is_generator : false ,
268- is_async_body : false ,
266+ generator_kind : None ,
269267 current_item : None ,
270268 lifetimes_to_define : Vec :: new ( ) ,
271269 is_collecting_in_band_lifetimes : false ,
@@ -795,18 +793,49 @@ impl<'a> LoweringContext<'a> {
795793 } )
796794 }
797795
798- fn record_body ( & mut self , arguments : HirVec < hir:: Arg > , value : hir:: Expr ) -> hir:: BodyId {
799- if self . is_generator && self . is_async_body {
800- span_err ! (
801- self . sess,
802- value. span,
803- E0727 ,
804- "`async` generators are not yet supported" ,
805- ) ;
806- self . sess . abort_if_errors ( ) ;
796+ fn generator_movability_for_fn (
797+ & mut self ,
798+ decl : & ast:: FnDecl ,
799+ fn_decl_span : Span ,
800+ generator_kind : Option < hir:: GeneratorKind > ,
801+ movability : Movability ,
802+ ) -> Option < hir:: GeneratorMovability > {
803+ match generator_kind {
804+ Some ( hir:: GeneratorKind :: Gen ) => {
805+ if !decl. inputs . is_empty ( ) {
806+ span_err ! (
807+ self . sess,
808+ fn_decl_span,
809+ E0628 ,
810+ "generators cannot have explicit arguments"
811+ ) ;
812+ self . sess . abort_if_errors ( ) ;
813+ }
814+ Some ( match movability {
815+ Movability :: Movable => hir:: GeneratorMovability :: Movable ,
816+ Movability :: Static => hir:: GeneratorMovability :: Static ,
817+ } )
818+ } ,
819+ Some ( hir:: GeneratorKind :: Async ) => {
820+ bug ! ( "non-`async` closure body turned `async` during lowering" ) ;
821+ } ,
822+ None => {
823+ if movability == Movability :: Static {
824+ span_err ! (
825+ self . sess,
826+ fn_decl_span,
827+ E0697 ,
828+ "closures cannot be static"
829+ ) ;
830+ }
831+ None
832+ } ,
807833 }
834+ }
835+
836+ fn record_body ( & mut self , arguments : HirVec < hir:: Arg > , value : hir:: Expr ) -> hir:: BodyId {
808837 let body = hir:: Body {
809- is_generator : self . is_generator || self . is_async_body ,
838+ generator_kind : self . generator_kind ,
810839 arguments,
811840 value,
812841 } ;
@@ -1143,7 +1172,7 @@ impl<'a> LoweringContext<'a> {
11431172 } ;
11441173 let decl = self . lower_fn_decl ( & ast_decl, None , /* impl trait allowed */ false , None ) ;
11451174 let body_id = self . lower_fn_body ( & ast_decl, |this| {
1146- this. is_async_body = true ;
1175+ this. generator_kind = Some ( hir :: GeneratorKind :: Async ) ;
11471176 body ( this)
11481177 } ) ;
11491178 let generator = hir:: Expr {
@@ -1168,12 +1197,10 @@ impl<'a> LoweringContext<'a> {
11681197 & mut self ,
11691198 f : impl FnOnce ( & mut LoweringContext < ' _ > ) -> ( HirVec < hir:: Arg > , hir:: Expr ) ,
11701199 ) -> hir:: BodyId {
1171- let prev_is_generator = mem:: replace ( & mut self . is_generator , false ) ;
1172- let prev_is_async_body = mem:: replace ( & mut self . is_async_body , false ) ;
1200+ let prev_gen_kind = self . generator_kind . take ( ) ;
11731201 let ( arguments, result) = f ( self ) ;
11741202 let body_id = self . record_body ( arguments, result) ;
1175- self . is_generator = prev_is_generator;
1176- self . is_async_body = prev_is_async_body;
1203+ self . generator_kind = prev_gen_kind;
11771204 body_id
11781205 }
11791206
@@ -4476,37 +4503,18 @@ impl<'a> LoweringContext<'a> {
44764503
44774504 self . with_new_scopes ( |this| {
44784505 this. current_item = Some ( fn_decl_span) ;
4479- let mut is_generator = false ;
4506+ let mut generator_kind = None ;
44804507 let body_id = this. lower_fn_body ( decl, |this| {
44814508 let e = this. lower_expr ( body) ;
4482- is_generator = this. is_generator ;
4509+ generator_kind = this. generator_kind ;
44834510 e
44844511 } ) ;
4485- let generator_option = if is_generator {
4486- if !decl. inputs . is_empty ( ) {
4487- span_err ! (
4488- this. sess,
4489- fn_decl_span,
4490- E0628 ,
4491- "generators cannot have explicit arguments"
4492- ) ;
4493- this. sess . abort_if_errors ( ) ;
4494- }
4495- Some ( match movability {
4496- Movability :: Movable => hir:: GeneratorMovability :: Movable ,
4497- Movability :: Static => hir:: GeneratorMovability :: Static ,
4498- } )
4499- } else {
4500- if movability == Movability :: Static {
4501- span_err ! (
4502- this. sess,
4503- fn_decl_span,
4504- E0697 ,
4505- "closures cannot be static"
4506- ) ;
4507- }
4508- None
4509- } ;
4512+ let generator_option = this. generator_movability_for_fn (
4513+ & decl,
4514+ fn_decl_span,
4515+ generator_kind,
4516+ movability,
4517+ ) ;
45104518 hir:: ExprKind :: Closure (
45114519 this. lower_capture_clause ( capture_clause) ,
45124520 fn_decl,
@@ -4678,12 +4686,26 @@ impl<'a> LoweringContext<'a> {
46784686 }
46794687
46804688 ExprKind :: Yield ( ref opt_expr) => {
4681- self . is_generator = true ;
4689+ match self . generator_kind {
4690+ Some ( hir:: GeneratorKind :: Gen ) => { } ,
4691+ Some ( hir:: GeneratorKind :: Async ) => {
4692+ span_err ! (
4693+ self . sess,
4694+ e. span,
4695+ E0727 ,
4696+ "`async` generators are not yet supported" ,
4697+ ) ;
4698+ self . sess . abort_if_errors ( ) ;
4699+ } ,
4700+ None => {
4701+ self . generator_kind = Some ( hir:: GeneratorKind :: Gen ) ;
4702+ }
4703+ }
46824704 let expr = opt_expr
46834705 . as_ref ( )
46844706 . map ( |x| self . lower_expr ( x) )
46854707 . unwrap_or_else ( || self . expr_unit ( e. span ) ) ;
4686- hir:: ExprKind :: Yield ( P ( expr) )
4708+ hir:: ExprKind :: Yield ( P ( expr) , hir :: YieldSource :: Yield )
46874709 }
46884710
46894711 ExprKind :: Err => hir:: ExprKind :: Err ,
@@ -5755,19 +5777,23 @@ impl<'a> LoweringContext<'a> {
57555777 // yield ();
57565778 // }
57575779 // }
5758- if !self . is_async_body {
5759- let mut err = struct_span_err ! (
5760- self . sess,
5761- await_span,
5762- E0728 ,
5763- "`await` is only allowed inside `async` functions and blocks"
5764- ) ;
5765- err. span_label ( await_span, "only allowed inside `async` functions and blocks" ) ;
5766- if let Some ( item_sp) = self . current_item {
5767- err. span_label ( item_sp, "this is not `async`" ) ;
5780+ match self . generator_kind {
5781+ Some ( hir:: GeneratorKind :: Async ) => { } ,
5782+ Some ( hir:: GeneratorKind :: Gen ) |
5783+ None => {
5784+ let mut err = struct_span_err ! (
5785+ self . sess,
5786+ await_span,
5787+ E0728 ,
5788+ "`await` is only allowed inside `async` functions and blocks"
5789+ ) ;
5790+ err. span_label ( await_span, "only allowed inside `async` functions and blocks" ) ;
5791+ if let Some ( item_sp) = self . current_item {
5792+ err. span_label ( item_sp, "this is not `async`" ) ;
5793+ }
5794+ err. emit ( ) ;
5795+ return hir:: ExprKind :: Err ;
57685796 }
5769- err. emit ( ) ;
5770- return hir:: ExprKind :: Err ;
57715797 }
57725798 let span = self . mark_span_with_reason (
57735799 CompilerDesugaringKind :: Await ,
@@ -5865,7 +5891,7 @@ impl<'a> LoweringContext<'a> {
58655891 let unit = self . expr_unit ( span) ;
58665892 let yield_expr = P ( self . expr (
58675893 span,
5868- hir:: ExprKind :: Yield ( P ( unit) ) ,
5894+ hir:: ExprKind :: Yield ( P ( unit) , hir :: YieldSource :: Await ) ,
58695895 ThinVec :: new ( ) ,
58705896 ) ) ;
58715897 self . stmt ( span, hir:: StmtKind :: Expr ( yield_expr) )
0 commit comments