@@ -95,8 +95,7 @@ pub struct LoweringContext<'a> {
95
95
96
96
modules : BTreeMap < NodeId , hir:: ModuleItems > ,
97
97
98
- is_generator : bool ,
99
- is_async_body : bool ,
98
+ generator_kind : Option < hir:: GeneratorKind > ,
100
99
101
100
/// Used to get the current `fn`'s def span to point to when using `await`
102
101
/// outside of an `async fn`.
@@ -261,8 +260,7 @@ pub fn lower_crate(
261
260
current_hir_id_owner : vec ! [ ( CRATE_DEF_INDEX , 0 ) ] ,
262
261
item_local_id_counters : Default :: default ( ) ,
263
262
node_id_to_hir_id : IndexVec :: new ( ) ,
264
- is_generator : false ,
265
- is_async_body : false ,
263
+ generator_kind : None ,
266
264
current_item : None ,
267
265
lifetimes_to_define : Vec :: new ( ) ,
268
266
is_collecting_in_band_lifetimes : false ,
@@ -790,18 +788,49 @@ impl<'a> LoweringContext<'a> {
790
788
} )
791
789
}
792
790
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
+ } ,
802
828
}
829
+ }
830
+
831
+ fn record_body ( & mut self , arguments : HirVec < hir:: Arg > , value : hir:: Expr ) -> hir:: BodyId {
803
832
let body = hir:: Body {
804
- is_generator : self . is_generator || self . is_async_body ,
833
+ generator_kind : self . generator_kind ,
805
834
arguments,
806
835
value,
807
836
} ;
@@ -1142,7 +1171,7 @@ impl<'a> LoweringContext<'a> {
1142
1171
} ;
1143
1172
let decl = self . lower_fn_decl ( & ast_decl, None , /* impl trait allowed */ false , None ) ;
1144
1173
let body_id = self . lower_fn_body ( & ast_decl, |this| {
1145
- this. is_async_body = true ;
1174
+ this. generator_kind = Some ( hir :: GeneratorKind :: Async ) ;
1146
1175
body ( this)
1147
1176
} ) ;
1148
1177
let generator = hir:: Expr {
@@ -1167,12 +1196,10 @@ impl<'a> LoweringContext<'a> {
1167
1196
& mut self ,
1168
1197
f : impl FnOnce ( & mut LoweringContext < ' _ > ) -> ( HirVec < hir:: Arg > , hir:: Expr ) ,
1169
1198
) -> 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 ( ) ;
1172
1200
let ( arguments, result) = f ( self ) ;
1173
1201
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;
1176
1203
body_id
1177
1204
}
1178
1205
@@ -4475,37 +4502,18 @@ impl<'a> LoweringContext<'a> {
4475
4502
4476
4503
self . with_new_scopes ( |this| {
4477
4504
this. current_item = Some ( fn_decl_span) ;
4478
- let mut is_generator = false ;
4505
+ let mut generator_kind = None ;
4479
4506
let body_id = this. lower_fn_body ( decl, |this| {
4480
4507
let e = this. lower_expr ( body) ;
4481
- is_generator = this. is_generator ;
4508
+ generator_kind = this. generator_kind ;
4482
4509
e
4483
4510
} ) ;
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
+ ) ;
4509
4517
hir:: ExprKind :: Closure (
4510
4518
this. lower_capture_clause ( capture_clause) ,
4511
4519
fn_decl,
@@ -4677,12 +4685,26 @@ impl<'a> LoweringContext<'a> {
4677
4685
}
4678
4686
4679
4687
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
+ }
4681
4703
let expr = opt_expr
4682
4704
. as_ref ( )
4683
4705
. map ( |x| self . lower_expr ( x) )
4684
4706
. unwrap_or_else ( || self . expr_unit ( e. span ) ) ;
4685
- hir:: ExprKind :: Yield ( P ( expr) )
4707
+ hir:: ExprKind :: Yield ( P ( expr) , hir :: YieldSource :: Yield )
4686
4708
}
4687
4709
4688
4710
ExprKind :: Err => hir:: ExprKind :: Err ,
@@ -5754,19 +5776,23 @@ impl<'a> LoweringContext<'a> {
5754
5776
// yield ();
5755
5777
// }
5756
5778
// }
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 ;
5767
5795
}
5768
- err. emit ( ) ;
5769
- return hir:: ExprKind :: Err ;
5770
5796
}
5771
5797
let span = self . mark_span_with_reason (
5772
5798
CompilerDesugaringKind :: Await ,
@@ -5864,7 +5890,7 @@ impl<'a> LoweringContext<'a> {
5864
5890
let unit = self . expr_unit ( span) ;
5865
5891
let yield_expr = P ( self . expr (
5866
5892
span,
5867
- hir:: ExprKind :: Yield ( P ( unit) ) ,
5893
+ hir:: ExprKind :: Yield ( P ( unit) , hir :: YieldSource :: Await ) ,
5868
5894
ThinVec :: new ( ) ,
5869
5895
) ) ;
5870
5896
self . stmt ( span, hir:: StmtKind :: Expr ( yield_expr) )
0 commit comments