@@ -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`.
@@ -264,8 +263,7 @@ pub fn lower_crate(
264
263
current_hir_id_owner : vec ! [ ( CRATE_DEF_INDEX , 0 ) ] ,
265
264
item_local_id_counters : Default :: default ( ) ,
266
265
node_id_to_hir_id : IndexVec :: new ( ) ,
267
- is_generator : false ,
268
- is_async_body : false ,
266
+ generator_kind : None ,
269
267
current_item : None ,
270
268
lifetimes_to_define : Vec :: new ( ) ,
271
269
is_collecting_in_band_lifetimes : false ,
@@ -795,18 +793,49 @@ impl<'a> LoweringContext<'a> {
795
793
} )
796
794
}
797
795
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
+ } ,
807
833
}
834
+ }
835
+
836
+ fn record_body ( & mut self , arguments : HirVec < hir:: Arg > , value : hir:: Expr ) -> hir:: BodyId {
808
837
let body = hir:: Body {
809
- is_generator : self . is_generator || self . is_async_body ,
838
+ generator_kind : self . generator_kind ,
810
839
arguments,
811
840
value,
812
841
} ;
@@ -1143,7 +1172,7 @@ impl<'a> LoweringContext<'a> {
1143
1172
} ;
1144
1173
let decl = self . lower_fn_decl ( & ast_decl, None , /* impl trait allowed */ false , None ) ;
1145
1174
let body_id = self . lower_fn_body ( & ast_decl, |this| {
1146
- this. is_async_body = true ;
1175
+ this. generator_kind = Some ( hir :: GeneratorKind :: Async ) ;
1147
1176
body ( this)
1148
1177
} ) ;
1149
1178
let generator = hir:: Expr {
@@ -1168,12 +1197,10 @@ impl<'a> LoweringContext<'a> {
1168
1197
& mut self ,
1169
1198
f : impl FnOnce ( & mut LoweringContext < ' _ > ) -> ( HirVec < hir:: Arg > , hir:: Expr ) ,
1170
1199
) -> 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 ( ) ;
1173
1201
let ( arguments, result) = f ( self ) ;
1174
1202
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;
1177
1204
body_id
1178
1205
}
1179
1206
@@ -4476,37 +4503,18 @@ impl<'a> LoweringContext<'a> {
4476
4503
4477
4504
self . with_new_scopes ( |this| {
4478
4505
this. current_item = Some ( fn_decl_span) ;
4479
- let mut is_generator = false ;
4506
+ let mut generator_kind = None ;
4480
4507
let body_id = this. lower_fn_body ( decl, |this| {
4481
4508
let e = this. lower_expr ( body) ;
4482
- is_generator = this. is_generator ;
4509
+ generator_kind = this. generator_kind ;
4483
4510
e
4484
4511
} ) ;
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
+ ) ;
4510
4518
hir:: ExprKind :: Closure (
4511
4519
this. lower_capture_clause ( capture_clause) ,
4512
4520
fn_decl,
@@ -4678,12 +4686,26 @@ impl<'a> LoweringContext<'a> {
4678
4686
}
4679
4687
4680
4688
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
+ }
4682
4704
let expr = opt_expr
4683
4705
. as_ref ( )
4684
4706
. map ( |x| self . lower_expr ( x) )
4685
4707
. unwrap_or_else ( || self . expr_unit ( e. span ) ) ;
4686
- hir:: ExprKind :: Yield ( P ( expr) )
4708
+ hir:: ExprKind :: Yield ( P ( expr) , hir :: YieldSource :: Yield )
4687
4709
}
4688
4710
4689
4711
ExprKind :: Err => hir:: ExprKind :: Err ,
@@ -5755,19 +5777,23 @@ impl<'a> LoweringContext<'a> {
5755
5777
// yield ();
5756
5778
// }
5757
5779
// }
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 ;
5768
5796
}
5769
- err. emit ( ) ;
5770
- return hir:: ExprKind :: Err ;
5771
5797
}
5772
5798
let span = self . mark_span_with_reason (
5773
5799
CompilerDesugaringKind :: Await ,
@@ -5865,7 +5891,7 @@ impl<'a> LoweringContext<'a> {
5865
5891
let unit = self . expr_unit ( span) ;
5866
5892
let yield_expr = P ( self . expr (
5867
5893
span,
5868
- hir:: ExprKind :: Yield ( P ( unit) ) ,
5894
+ hir:: ExprKind :: Yield ( P ( unit) , hir :: YieldSource :: Await ) ,
5869
5895
ThinVec :: new ( ) ,
5870
5896
) ) ;
5871
5897
self . stmt ( span, hir:: StmtKind :: Expr ( yield_expr) )
0 commit comments