@@ -162,35 +162,7 @@ impl<'a> InferenceContext<'a> {
162
162
. 1
163
163
}
164
164
Expr :: Async { id, statements, tail } => {
165
- let ret_ty = self . table . new_type_var ( ) ;
166
- let prev_diverges = mem:: replace ( & mut self . diverges , Diverges :: Maybe ) ;
167
- let prev_ret_ty = mem:: replace ( & mut self . return_ty , ret_ty. clone ( ) ) ;
168
- let prev_ret_coercion =
169
- mem:: replace ( & mut self . return_coercion , Some ( CoerceMany :: new ( ret_ty. clone ( ) ) ) ) ;
170
-
171
- let ( _, inner_ty) =
172
- self . with_breakable_ctx ( BreakableKind :: Border , None , None , |this| {
173
- this. infer_block (
174
- tgt_expr,
175
- * id,
176
- statements,
177
- * tail,
178
- None ,
179
- & Expectation :: has_type ( ret_ty) ,
180
- )
181
- } ) ;
182
-
183
- self . diverges = prev_diverges;
184
- self . return_ty = prev_ret_ty;
185
- self . return_coercion = prev_ret_coercion;
186
-
187
- // Use the first type parameter as the output type of future.
188
- // existential type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
189
- let impl_trait_id =
190
- crate :: ImplTraitId :: AsyncBlockTypeImplTrait ( self . owner , tgt_expr) ;
191
- let opaque_ty_id = self . db . intern_impl_trait_id ( impl_trait_id) . into ( ) ;
192
- TyKind :: OpaqueType ( opaque_ty_id, Substitution :: from1 ( Interner , inner_ty) )
193
- . intern ( Interner )
165
+ self . infer_async_block ( tgt_expr, id, statements, tail)
194
166
}
195
167
& Expr :: Loop { body, label } => {
196
168
// FIXME: should be:
@@ -260,18 +232,7 @@ impl<'a> InferenceContext<'a> {
260
232
None => self . table . new_type_var ( ) ,
261
233
} ;
262
234
if let ClosureKind :: Async = closure_kind {
263
- // Use the first type parameter as the output type of future.
264
- // existential type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
265
- let impl_trait_id =
266
- crate :: ImplTraitId :: AsyncBlockTypeImplTrait ( self . owner , * body) ;
267
- let opaque_ty_id = self . db . intern_impl_trait_id ( impl_trait_id) . into ( ) ;
268
- sig_tys. push (
269
- TyKind :: OpaqueType (
270
- opaque_ty_id,
271
- Substitution :: from1 ( Interner , ret_ty. clone ( ) ) ,
272
- )
273
- . intern ( Interner ) ,
274
- ) ;
235
+ sig_tys. push ( self . lower_async_block_type_impl_trait ( ret_ty. clone ( ) , * body) ) ;
275
236
} else {
276
237
sig_tys. push ( ret_ty. clone ( ) ) ;
277
238
}
@@ -332,6 +293,7 @@ impl<'a> InferenceContext<'a> {
332
293
333
294
// FIXME: lift these out into a struct
334
295
let prev_diverges = mem:: replace ( & mut self . diverges , Diverges :: Maybe ) ;
296
+ let prev_is_async_fn = mem:: replace ( & mut self . is_async_fn , false ) ;
335
297
let prev_ret_ty = mem:: replace ( & mut self . return_ty , ret_ty. clone ( ) ) ;
336
298
let prev_ret_coercion =
337
299
mem:: replace ( & mut self . return_coercion , Some ( CoerceMany :: new ( ret_ty) ) ) ;
@@ -345,6 +307,7 @@ impl<'a> InferenceContext<'a> {
345
307
self . diverges = prev_diverges;
346
308
self . return_ty = prev_ret_ty;
347
309
self . return_coercion = prev_ret_coercion;
310
+ self . is_async_fn = prev_is_async_fn;
348
311
self . resume_yield_tys = prev_resume_yield_tys;
349
312
350
313
ty
@@ -900,6 +863,42 @@ impl<'a> InferenceContext<'a> {
900
863
ty
901
864
}
902
865
866
+ fn infer_async_block (
867
+ & mut self ,
868
+ tgt_expr : ExprId ,
869
+ id : & Option < BlockId > ,
870
+ statements : & [ Statement ] ,
871
+ tail : & Option < ExprId > ,
872
+ ) -> Ty {
873
+ let ret_ty = self . table . new_type_var ( ) ;
874
+ let prev_diverges = mem:: replace ( & mut self . diverges , Diverges :: Maybe ) ;
875
+ let prev_ret_ty = mem:: replace ( & mut self . return_ty , ret_ty. clone ( ) ) ;
876
+ let prev_ret_coercion =
877
+ mem:: replace ( & mut self . return_coercion , Some ( CoerceMany :: new ( ret_ty. clone ( ) ) ) ) ;
878
+
879
+ let ( _, inner_ty) = self . with_breakable_ctx ( BreakableKind :: Border , None , None , |this| {
880
+ this. infer_block ( tgt_expr, * id, statements, * tail, None , & Expectation :: has_type ( ret_ty) )
881
+ } ) ;
882
+
883
+ self . diverges = prev_diverges;
884
+ self . return_ty = prev_ret_ty;
885
+ self . return_coercion = prev_ret_coercion;
886
+
887
+ self . lower_async_block_type_impl_trait ( inner_ty, tgt_expr)
888
+ }
889
+
890
+ pub ( crate ) fn lower_async_block_type_impl_trait (
891
+ & mut self ,
892
+ inner_ty : Ty ,
893
+ tgt_expr : ExprId ,
894
+ ) -> Ty {
895
+ // Use the first type parameter as the output type of future.
896
+ // existential type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
897
+ let impl_trait_id = crate :: ImplTraitId :: AsyncBlockTypeImplTrait ( self . owner , tgt_expr) ;
898
+ let opaque_ty_id = self . db . intern_impl_trait_id ( impl_trait_id) . into ( ) ;
899
+ TyKind :: OpaqueType ( opaque_ty_id, Substitution :: from1 ( Interner , inner_ty) ) . intern ( Interner )
900
+ }
901
+
903
902
fn infer_expr_array (
904
903
& mut self ,
905
904
array : & Array ,
@@ -964,7 +963,11 @@ impl<'a> InferenceContext<'a> {
964
963
. as_mut ( )
965
964
. expect ( "infer_return called outside function body" )
966
965
. expected_ty ( ) ;
967
- let return_expr_ty = self . infer_expr_inner ( expr, & Expectation :: HasType ( ret_ty) ) ;
966
+ let return_expr_ty = if self . is_async_fn {
967
+ self . infer_async_block ( expr, & None , & [ ] , & Some ( expr) )
968
+ } else {
969
+ self . infer_expr_inner ( expr, & Expectation :: HasType ( ret_ty) )
970
+ } ;
968
971
let mut coerce_many = self . return_coercion . take ( ) . unwrap ( ) ;
969
972
coerce_many. coerce ( self , Some ( expr) , & return_expr_ty) ;
970
973
self . return_coercion = Some ( coerce_many) ;
0 commit comments