@@ -275,7 +275,23 @@ impl<'a> InferenceContext<'a> {
275275 Some ( type_ref) => self . make_ty ( type_ref) ,
276276 None => self . table . new_type_var ( ) ,
277277 } ;
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+
279295 let sig_ty = TyKind :: Function ( FnPointer {
280296 num_binders : 0 ,
281297 sig : FnSig { abi : ( ) , safety : chalk_ir:: Safety :: Safe , variadic : false } ,
@@ -286,33 +302,38 @@ impl<'a> InferenceContext<'a> {
286302 } )
287303 . intern ( Interner ) ;
288304
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 ( ) ;
304321
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 ) ;
307324
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 ) ;
314334
315- ( closure_ty, None )
335+ ( closure_ty, None )
336+ }
316337 } ;
317338
318339 // Eagerly try to relate the closure type with the expected
@@ -321,7 +342,7 @@ impl<'a> InferenceContext<'a> {
321342 self . deduce_closure_type_from_expectations ( tgt_expr, & ty, & sig_ty, expected) ;
322343
323344 // 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) {
325346 self . infer_top_pat ( * arg_pat, & arg_ty) ;
326347 }
327348
0 commit comments