@@ -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`.
@@ -261,8 +260,7 @@ pub fn lower_crate(
261260 current_hir_id_owner : vec ! [ ( CRATE_DEF_INDEX , 0 ) ] ,
262261 item_local_id_counters : Default :: default ( ) ,
263262 node_id_to_hir_id : IndexVec :: new ( ) ,
264- is_generator : false ,
265- is_async_body : false ,
263+ generator_kind : None ,
266264 current_item : None ,
267265 lifetimes_to_define : Vec :: new ( ) ,
268266 is_collecting_in_band_lifetimes : false ,
@@ -790,18 +788,49 @@ impl<'a> LoweringContext<'a> {
790788 } )
791789 }
792790
793- fn record_body ( & mut self , arguments : HirVec < hir:: Arg > , value : hir:: Expr ) -> hir:: BodyId {
794- if self . is_generator && self . is_async_body {
795- span_err ! (
796- self . sess,
797- value. span,
798- E0727 ,
799- "`async` generators are not yet supported" ,
800- ) ;
801- self . sess . abort_if_errors ( ) ;
791+ fn generator_movability_for_fn (
792+ & mut self ,
793+ decl : & ast:: FnDecl ,
794+ fn_decl_span : Span ,
795+ generator_kind : Option < hir:: GeneratorKind > ,
796+ movability : Movability ,
797+ ) -> Option < hir:: GeneratorMovability > {
798+ match generator_kind {
799+ Some ( hir:: GeneratorKind :: Gen ) => {
800+ if !decl. inputs . is_empty ( ) {
801+ span_err ! (
802+ self . sess,
803+ fn_decl_span,
804+ E0628 ,
805+ "generators cannot have explicit arguments"
806+ ) ;
807+ self . sess . abort_if_errors ( ) ;
808+ }
809+ Some ( match movability {
810+ Movability :: Movable => hir:: GeneratorMovability :: Movable ,
811+ Movability :: Static => hir:: GeneratorMovability :: Static ,
812+ } )
813+ } ,
814+ Some ( hir:: GeneratorKind :: Async ) => {
815+ bug ! ( "non-`async` closure body turned `async` during lowering" ) ;
816+ } ,
817+ None => {
818+ if movability == Movability :: Static {
819+ span_err ! (
820+ self . sess,
821+ fn_decl_span,
822+ E0697 ,
823+ "closures cannot be static"
824+ ) ;
825+ }
826+ None
827+ } ,
802828 }
829+ }
830+
831+ fn record_body ( & mut self , arguments : HirVec < hir:: Arg > , value : hir:: Expr ) -> hir:: BodyId {
803832 let body = hir:: Body {
804- is_generator : self . is_generator || self . is_async_body ,
833+ generator_kind : self . generator_kind ,
805834 arguments,
806835 value,
807836 } ;
@@ -1142,7 +1171,7 @@ impl<'a> LoweringContext<'a> {
11421171 } ;
11431172 let decl = self . lower_fn_decl ( & ast_decl, None , /* impl trait allowed */ false , None ) ;
11441173 let body_id = self . lower_fn_body ( & ast_decl, |this| {
1145- this. is_async_body = true ;
1174+ this. generator_kind = Some ( hir :: GeneratorKind :: Async ) ;
11461175 body ( this)
11471176 } ) ;
11481177 let generator = hir:: Expr {
@@ -1167,12 +1196,10 @@ impl<'a> LoweringContext<'a> {
11671196 & mut self ,
11681197 f : impl FnOnce ( & mut LoweringContext < ' _ > ) -> ( HirVec < hir:: Arg > , hir:: Expr ) ,
11691198 ) -> hir:: BodyId {
1170- let prev_is_generator = mem:: replace ( & mut self . is_generator , false ) ;
1171- let prev_is_async_body = mem:: replace ( & mut self . is_async_body , false ) ;
1199+ let prev_gen_kind = self . generator_kind . take ( ) ;
11721200 let ( arguments, result) = f ( self ) ;
11731201 let body_id = self . record_body ( arguments, result) ;
1174- self . is_generator = prev_is_generator;
1175- self . is_async_body = prev_is_async_body;
1202+ self . generator_kind = prev_gen_kind;
11761203 body_id
11771204 }
11781205
@@ -4475,37 +4502,18 @@ impl<'a> LoweringContext<'a> {
44754502
44764503 self . with_new_scopes ( |this| {
44774504 this. current_item = Some ( fn_decl_span) ;
4478- let mut is_generator = false ;
4505+ let mut generator_kind = None ;
44794506 let body_id = this. lower_fn_body ( decl, |this| {
44804507 let e = this. lower_expr ( body) ;
4481- is_generator = this. is_generator ;
4508+ generator_kind = this. generator_kind ;
44824509 e
44834510 } ) ;
4484- let generator_option = if is_generator {
4485- if !decl. inputs . is_empty ( ) {
4486- span_err ! (
4487- this. sess,
4488- fn_decl_span,
4489- E0628 ,
4490- "generators cannot have explicit arguments"
4491- ) ;
4492- this. sess . abort_if_errors ( ) ;
4493- }
4494- Some ( match movability {
4495- Movability :: Movable => hir:: GeneratorMovability :: Movable ,
4496- Movability :: Static => hir:: GeneratorMovability :: Static ,
4497- } )
4498- } else {
4499- if movability == Movability :: Static {
4500- span_err ! (
4501- this. sess,
4502- fn_decl_span,
4503- E0697 ,
4504- "closures cannot be static"
4505- ) ;
4506- }
4507- None
4508- } ;
4511+ let generator_option = this. generator_movability_for_fn (
4512+ & decl,
4513+ fn_decl_span,
4514+ generator_kind,
4515+ movability,
4516+ ) ;
45094517 hir:: ExprKind :: Closure (
45104518 this. lower_capture_clause ( capture_clause) ,
45114519 fn_decl,
@@ -4677,12 +4685,26 @@ impl<'a> LoweringContext<'a> {
46774685 }
46784686
46794687 ExprKind :: Yield ( ref opt_expr) => {
4680- self . is_generator = true ;
4688+ match self . generator_kind {
4689+ Some ( hir:: GeneratorKind :: Gen ) => { } ,
4690+ Some ( hir:: GeneratorKind :: Async ) => {
4691+ span_err ! (
4692+ self . sess,
4693+ e. span,
4694+ E0727 ,
4695+ "`async` generators are not yet supported" ,
4696+ ) ;
4697+ self . sess . abort_if_errors ( ) ;
4698+ } ,
4699+ None => {
4700+ self . generator_kind = Some ( hir:: GeneratorKind :: Gen ) ;
4701+ }
4702+ }
46814703 let expr = opt_expr
46824704 . as_ref ( )
46834705 . map ( |x| self . lower_expr ( x) )
46844706 . unwrap_or_else ( || self . expr_unit ( e. span ) ) ;
4685- hir:: ExprKind :: Yield ( P ( expr) )
4707+ hir:: ExprKind :: Yield ( P ( expr) , hir :: YieldSource :: Yield )
46864708 }
46874709
46884710 ExprKind :: Err => hir:: ExprKind :: Err ,
@@ -5754,19 +5776,23 @@ impl<'a> LoweringContext<'a> {
57545776 // yield ();
57555777 // }
57565778 // }
5757- if !self . is_async_body {
5758- let mut err = struct_span_err ! (
5759- self . sess,
5760- await_span,
5761- E0728 ,
5762- "`await` is only allowed inside `async` functions and blocks"
5763- ) ;
5764- err. span_label ( await_span, "only allowed inside `async` functions and blocks" ) ;
5765- if let Some ( item_sp) = self . current_item {
5766- err. span_label ( item_sp, "this is not `async`" ) ;
5779+ match self . generator_kind {
5780+ Some ( hir:: GeneratorKind :: Async ) => { } ,
5781+ Some ( hir:: GeneratorKind :: Gen ) |
5782+ None => {
5783+ let mut err = struct_span_err ! (
5784+ self . sess,
5785+ await_span,
5786+ E0728 ,
5787+ "`await` is only allowed inside `async` functions and blocks"
5788+ ) ;
5789+ err. span_label ( await_span, "only allowed inside `async` functions and blocks" ) ;
5790+ if let Some ( item_sp) = self . current_item {
5791+ err. span_label ( item_sp, "this is not `async`" ) ;
5792+ }
5793+ err. emit ( ) ;
5794+ return hir:: ExprKind :: Err ;
57675795 }
5768- err. emit ( ) ;
5769- return hir:: ExprKind :: Err ;
57705796 }
57715797 let span = self . mark_span_with_reason (
57725798 CompilerDesugaringKind :: Await ,
@@ -5864,7 +5890,7 @@ impl<'a> LoweringContext<'a> {
58645890 let unit = self . expr_unit ( span) ;
58655891 let yield_expr = P ( self . expr (
58665892 span,
5867- hir:: ExprKind :: Yield ( P ( unit) ) ,
5893+ hir:: ExprKind :: Yield ( P ( unit) , hir :: YieldSource :: Await ) ,
58685894 ThinVec :: new ( ) ,
58695895 ) ) ;
58705896 self . stmt ( span, hir:: StmtKind :: Expr ( yield_expr) )
0 commit comments