@@ -218,7 +218,7 @@ impl<'a> InferenceContext<'a> {
218
218
self . diverges = Diverges :: Maybe ;
219
219
TyBuilder :: unit ( )
220
220
}
221
- Expr :: Closure { body, args, ret_type, arg_types } => {
221
+ Expr :: Closure { body, args, ret_type, arg_types, is_async } => {
222
222
assert_eq ! ( args. len( ) , arg_types. len( ) ) ;
223
223
224
224
let mut sig_tys = Vec :: new ( ) ;
@@ -262,19 +262,44 @@ impl<'a> InferenceContext<'a> {
262
262
) ;
263
263
264
264
// Now go through the argument patterns
265
- for ( arg_pat, arg_ty) in args. iter ( ) . zip ( sig_tys) {
265
+ for ( arg_pat, arg_ty) in args. iter ( ) . zip ( & sig_tys) {
266
266
self . infer_pat ( * arg_pat, & arg_ty, BindingMode :: default ( ) ) ;
267
267
}
268
268
269
269
let prev_diverges = mem:: replace ( & mut self . diverges , Diverges :: Maybe ) ;
270
270
let prev_ret_ty = mem:: replace ( & mut self . return_ty , ret_ty. clone ( ) ) ;
271
271
272
- self . infer_expr_coerce ( * body, & Expectation :: has_type ( ret_ty) ) ;
272
+ let inner_ty = self . infer_expr_coerce ( * body, & Expectation :: has_type ( ret_ty) ) ;
273
+
274
+ let inner_ty = if * is_async {
275
+ // Use the first type parameter as the output type of future.
276
+ // existential type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
277
+ let impl_trait_id =
278
+ crate :: ImplTraitId :: AsyncBlockTypeImplTrait ( self . owner , * body) ;
279
+ let opaque_ty_id = self . db . intern_impl_trait_id ( impl_trait_id) . into ( ) ;
280
+ TyKind :: OpaqueType ( opaque_ty_id, Substitution :: from1 ( Interner , inner_ty) )
281
+ . intern ( Interner )
282
+ } else {
283
+ inner_ty
284
+ } ;
273
285
274
286
self . diverges = prev_diverges;
275
287
self . return_ty = prev_ret_ty;
276
288
277
- closure_ty
289
+ sig_tys. pop ( ) ;
290
+ sig_tys. push ( inner_ty) ;
291
+
292
+ let sig_ty = TyKind :: Function ( FnPointer {
293
+ num_binders : 0 ,
294
+ sig : FnSig { abi : ( ) , safety : chalk_ir:: Safety :: Safe , variadic : false } ,
295
+ substitution : FnSubst (
296
+ Substitution :: from_iter ( Interner , sig_tys. clone ( ) ) . shifted_in ( Interner ) ,
297
+ ) ,
298
+ } )
299
+ . intern ( Interner ) ;
300
+
301
+ TyKind :: Closure ( closure_id, Substitution :: from1 ( Interner , sig_ty. clone ( ) ) )
302
+ . intern ( Interner )
278
303
}
279
304
Expr :: Call { callee, args, .. } => {
280
305
let callee_ty = self . infer_expr ( * callee, & Expectation :: none ( ) ) ;
0 commit comments