@@ -275,7 +275,23 @@ impl<'a> InferenceContext<'a> {
275
275
Some ( type_ref) => self . make_ty ( type_ref) ,
276
276
None => self . table . new_type_var ( ) ,
277
277
} ;
278
- sig_tys. push ( ret_ty. clone ( ) ) ;
278
+ if let ClosureKind :: Async = closure_kind {
279
+ // Use the first type parameter as the output type of future.
280
+ // existential type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
281
+ let impl_trait_id =
282
+ crate :: ImplTraitId :: AsyncBlockTypeImplTrait ( self . owner , * body) ;
283
+ let opaque_ty_id = self . db . intern_impl_trait_id ( impl_trait_id) . into ( ) ;
284
+ sig_tys. push (
285
+ TyKind :: OpaqueType (
286
+ opaque_ty_id,
287
+ Substitution :: from1 ( Interner , ret_ty. clone ( ) ) ,
288
+ )
289
+ . intern ( Interner ) ,
290
+ ) ;
291
+ } else {
292
+ sig_tys. push ( ret_ty. clone ( ) ) ;
293
+ }
294
+
279
295
let sig_ty = TyKind :: Function ( FnPointer {
280
296
num_binders : 0 ,
281
297
sig : FnSig { abi : ( ) , safety : chalk_ir:: Safety :: Safe , variadic : false } ,
@@ -286,33 +302,38 @@ impl<'a> InferenceContext<'a> {
286
302
} )
287
303
. intern ( Interner ) ;
288
304
289
- let ( ty, resume_yield_tys) = if matches ! ( closure_kind, ClosureKind :: Generator ( _) ) {
290
- // FIXME: report error when there are more than 1 parameter.
291
- let resume_ty = match sig_tys. first ( ) {
292
- // When `sig_tys.len() == 1` the first type is the return type, not the
293
- // first parameter type.
294
- Some ( ty) if sig_tys. len ( ) > 1 => ty. clone ( ) ,
295
- _ => self . result . standard_types . unit . clone ( ) ,
296
- } ;
297
- let yield_ty = self . table . new_type_var ( ) ;
298
-
299
- let subst = TyBuilder :: subst_for_generator ( self . db , self . owner )
300
- . push ( resume_ty. clone ( ) )
301
- . push ( yield_ty. clone ( ) )
302
- . push ( ret_ty. clone ( ) )
303
- . build ( ) ;
305
+ let ( ty, resume_yield_tys) = match closure_kind {
306
+ ClosureKind :: Generator ( _) => {
307
+ // FIXME: report error when there are more than 1 parameter.
308
+ let resume_ty = match sig_tys. first ( ) {
309
+ // When `sig_tys.len() == 1` the first type is the return type, not the
310
+ // first parameter type.
311
+ Some ( ty) if sig_tys. len ( ) > 1 => ty. clone ( ) ,
312
+ _ => self . result . standard_types . unit . clone ( ) ,
313
+ } ;
314
+ let yield_ty = self . table . new_type_var ( ) ;
315
+
316
+ let subst = TyBuilder :: subst_for_generator ( self . db , self . owner )
317
+ . push ( resume_ty. clone ( ) )
318
+ . push ( yield_ty. clone ( ) )
319
+ . push ( ret_ty. clone ( ) )
320
+ . build ( ) ;
304
321
305
- let generator_id = self . db . intern_generator ( ( self . owner , tgt_expr) ) . into ( ) ;
306
- let generator_ty = TyKind :: Generator ( generator_id, subst) . intern ( Interner ) ;
322
+ let generator_id = self . db . intern_generator ( ( self . owner , tgt_expr) ) . into ( ) ;
323
+ let generator_ty = TyKind :: Generator ( generator_id, subst) . intern ( Interner ) ;
307
324
308
- ( generator_ty, Some ( ( resume_ty, yield_ty) ) )
309
- } else {
310
- let closure_id = self . db . intern_closure ( ( self . owner , tgt_expr) ) . into ( ) ;
311
- let closure_ty =
312
- TyKind :: Closure ( closure_id, Substitution :: from1 ( Interner , sig_ty. clone ( ) ) )
313
- . intern ( Interner ) ;
325
+ ( generator_ty, Some ( ( resume_ty, yield_ty) ) )
326
+ }
327
+ ClosureKind :: Closure | ClosureKind :: Async => {
328
+ let closure_id = self . db . intern_closure ( ( self . owner , tgt_expr) ) . into ( ) ;
329
+ let closure_ty = TyKind :: Closure (
330
+ closure_id,
331
+ Substitution :: from1 ( Interner , sig_ty. clone ( ) ) ,
332
+ )
333
+ . intern ( Interner ) ;
314
334
315
- ( closure_ty, None )
335
+ ( closure_ty, None )
336
+ }
316
337
} ;
317
338
318
339
// Eagerly try to relate the closure type with the expected
@@ -321,7 +342,7 @@ impl<'a> InferenceContext<'a> {
321
342
self . deduce_closure_type_from_expectations ( tgt_expr, & ty, & sig_ty, expected) ;
322
343
323
344
// Now go through the argument patterns
324
- for ( arg_pat, arg_ty) in args. iter ( ) . zip ( sig_tys) {
345
+ for ( arg_pat, arg_ty) in args. iter ( ) . zip ( & sig_tys) {
325
346
self . infer_top_pat ( * arg_pat, & arg_ty) ;
326
347
}
327
348
0 commit comments