1+ use std:: assert_matches:: assert_matches;
2+
13use super :: errors:: {
24 AsyncCoroutinesNotSupported , AwaitOnlyInAsyncFnAndBlocks , BaseExpressionDoubleDot ,
35 ClosureCannotBeStatic , CoroutineTooManyParameters ,
46 FunctionalRecordUpdateDestructuringAssignment , InclusiveRangeWithNoEnd , MatchArmWithNoBody ,
5- NeverPatternWithBody , NeverPatternWithGuard , NotSupportedForLifetimeBinderAsyncClosure ,
6- UnderscoreExprLhsAssign ,
7+ NeverPatternWithBody , NeverPatternWithGuard , UnderscoreExprLhsAssign ,
78} ;
89use super :: ResolverAstLoweringExt ;
910use super :: { ImplTraitContext , LoweringContext , ParamMode , ParenthesizedGenericArgs } ;
@@ -1028,30 +1029,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
10281029 fn_decl_span : Span ,
10291030 fn_arg_span : Span ,
10301031 ) -> hir:: ExprKind < ' hir > {
1031- if let & ClosureBinder :: For { span, .. } = binder {
1032- self . dcx ( ) . emit_err ( NotSupportedForLifetimeBinderAsyncClosure { span } ) ;
1033- }
1034-
10351032 let ( binder_clause, generic_params) = self . lower_closure_binder ( binder) ;
10361033
1034+ assert_matches ! (
1035+ coroutine_kind,
1036+ CoroutineKind :: Async { .. } ,
1037+ "only async closures are supported currently"
1038+ ) ;
1039+
10371040 let body = self . with_new_scopes ( fn_decl_span, |this| {
1041+ let inner_decl =
1042+ FnDecl { inputs : decl. inputs . clone ( ) , output : FnRetTy :: Default ( fn_decl_span) } ;
1043+
10381044 // Transform `async |x: u8| -> X { ... }` into
10391045 // `|x: u8| || -> X { ... }`.
10401046 let body_id = this. lower_body ( |this| {
1041- let async_ret_ty = if let FnRetTy :: Ty ( ty) = & decl. output {
1042- let itctx = ImplTraitContext :: Disallowed ( ImplTraitPosition :: AsyncBlock ) ;
1043- Some ( hir:: FnRetTy :: Return ( this. lower_ty ( ty, & itctx) ) )
1044- } else {
1045- None
1046- } ;
1047-
10481047 let ( parameters, expr) = this. lower_coroutine_body_with_moved_arguments (
1049- decl ,
1048+ & inner_decl ,
10501049 |this| this. with_new_scopes ( fn_decl_span, |this| this. lower_expr_mut ( body) ) ,
10511050 body. span ,
10521051 coroutine_kind,
10531052 hir:: CoroutineSource :: Closure ,
1054- async_ret_ty,
10551053 ) ;
10561054
10571055 let hir_id = this. lower_node_id ( coroutine_kind. closure_id ( ) ) ;
@@ -1062,15 +1060,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
10621060 body_id
10631061 } ) ;
10641062
1065- let outer_decl =
1066- FnDecl { inputs : decl. inputs . clone ( ) , output : FnRetTy :: Default ( fn_decl_span) } ;
1067-
10681063 let bound_generic_params = self . lower_lifetime_binder ( closure_id, generic_params) ;
10691064 // We need to lower the declaration outside the new scope, because we
10701065 // have to conserve the state of being inside a loop condition for the
10711066 // closure argument types.
10721067 let fn_decl =
1073- self . lower_fn_decl ( & outer_decl , closure_id, fn_decl_span, FnDeclKind :: Closure , None ) ;
1068+ self . lower_fn_decl ( & decl , closure_id, fn_decl_span, FnDeclKind :: Closure , None ) ;
10741069
10751070 let c = self . arena . alloc ( hir:: Closure {
10761071 def_id : self . local_def_id ( closure_id) ,
@@ -1081,7 +1076,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
10811076 body,
10821077 fn_decl_span : self . lower_span ( fn_decl_span) ,
10831078 fn_arg_span : Some ( self . lower_span ( fn_arg_span) ) ,
1084- kind : hir:: ClosureKind :: Closure ,
1079+ // Lower this as a `CoroutineClosure`. That will ensure that HIR typeck
1080+ // knows that a `FnDecl` output type like `-> &str` actually means
1081+ // "coroutine that returns &str", rather than directly returning a `&str`.
1082+ kind : hir:: ClosureKind :: CoroutineClosure ( hir:: CoroutineDesugaring :: Async ) ,
10851083 constness : hir:: Constness :: NotConst ,
10861084 } ) ;
10871085 hir:: ExprKind :: Closure ( c)
0 commit comments