1
+ use std:: assert_matches:: assert_matches;
2
+
1
3
use super :: errors:: {
2
4
AsyncCoroutinesNotSupported , AwaitOnlyInAsyncFnAndBlocks , BaseExpressionDoubleDot ,
3
5
ClosureCannotBeStatic , CoroutineTooManyParameters ,
4
6
FunctionalRecordUpdateDestructuringAssignment , InclusiveRangeWithNoEnd , MatchArmWithNoBody ,
5
- NeverPatternWithBody , NeverPatternWithGuard , NotSupportedForLifetimeBinderAsyncClosure ,
6
- UnderscoreExprLhsAssign ,
7
+ NeverPatternWithBody , NeverPatternWithGuard , UnderscoreExprLhsAssign ,
7
8
} ;
8
9
use super :: ResolverAstLoweringExt ;
9
10
use super :: { ImplTraitContext , LoweringContext , ParamMode , ParenthesizedGenericArgs } ;
@@ -1028,30 +1029,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
1028
1029
fn_decl_span : Span ,
1029
1030
fn_arg_span : Span ,
1030
1031
) -> hir:: ExprKind < ' hir > {
1031
- if let & ClosureBinder :: For { span, .. } = binder {
1032
- self . dcx ( ) . emit_err ( NotSupportedForLifetimeBinderAsyncClosure { span } ) ;
1033
- }
1034
-
1035
1032
let ( binder_clause, generic_params) = self . lower_closure_binder ( binder) ;
1036
1033
1034
+ assert_matches ! (
1035
+ coroutine_kind,
1036
+ CoroutineKind :: Async { .. } ,
1037
+ "only async closures are supported currently"
1038
+ ) ;
1039
+
1037
1040
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
+
1038
1044
// Transform `async |x: u8| -> X { ... }` into
1039
1045
// `|x: u8| || -> X { ... }`.
1040
1046
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
-
1048
1047
let ( parameters, expr) = this. lower_coroutine_body_with_moved_arguments (
1049
- decl ,
1048
+ & inner_decl ,
1050
1049
|this| this. with_new_scopes ( fn_decl_span, |this| this. lower_expr_mut ( body) ) ,
1051
1050
body. span ,
1052
1051
coroutine_kind,
1053
1052
hir:: CoroutineSource :: Closure ,
1054
- async_ret_ty,
1055
1053
) ;
1056
1054
1057
1055
let hir_id = this. lower_node_id ( coroutine_kind. closure_id ( ) ) ;
@@ -1062,15 +1060,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
1062
1060
body_id
1063
1061
} ) ;
1064
1062
1065
- let outer_decl =
1066
- FnDecl { inputs : decl. inputs . clone ( ) , output : FnRetTy :: Default ( fn_decl_span) } ;
1067
-
1068
1063
let bound_generic_params = self . lower_lifetime_binder ( closure_id, generic_params) ;
1069
1064
// We need to lower the declaration outside the new scope, because we
1070
1065
// have to conserve the state of being inside a loop condition for the
1071
1066
// closure argument types.
1072
1067
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 ) ;
1074
1069
1075
1070
let c = self . arena . alloc ( hir:: Closure {
1076
1071
def_id : self . local_def_id ( closure_id) ,
@@ -1081,7 +1076,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
1081
1076
body,
1082
1077
fn_decl_span : self . lower_span ( fn_decl_span) ,
1083
1078
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 ) ,
1085
1083
constness : hir:: Constness :: NotConst ,
1086
1084
} ) ;
1087
1085
hir:: ExprKind :: Closure ( c)
0 commit comments