]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_ast_lowering/src/expr.rs
Rollup merge of #99692 - RalfJung:too-far, r=oli-obk
[rust.git] / compiler / rustc_ast_lowering / src / expr.rs
index 9e02e7ed3b9cf0048e66d07435aa03b0c747e437..983efa48a457982bf8ab37e2b9f0651c68a990a7 100644 (file)
@@ -155,6 +155,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
                     self.lower_expr_await(span, expr)
                 }
                 ExprKind::Closure(
+                    ref binder,
                     capture_clause,
                     asyncness,
                     movability,
@@ -164,6 +165,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
                 ) => {
                     if let Async::Yes { closure_id, .. } = asyncness {
                         self.lower_expr_async_closure(
+                            binder,
                             capture_clause,
                             e.id,
                             closure_id,
@@ -173,6 +175,7 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'hir> {
                         )
                     } else {
                         self.lower_expr_closure(
+                            binder,
                             capture_clause,
                             e.id,
                             movability,
@@ -605,13 +608,18 @@ pub(super) fn make_async_expr(
         });
 
         // `static |_task_context| -> <ret_ty> { body }`:
-        let generator_kind = hir::ExprKind::Closure {
-            capture_clause,
-            bound_generic_params: &[],
-            fn_decl,
-            body,
-            fn_decl_span: self.lower_span(span),
-            movability: Some(hir::Movability::Static),
+        let generator_kind = {
+            let c = self.arena.alloc(hir::Closure {
+                binder: hir::ClosureBinder::Default,
+                capture_clause,
+                bound_generic_params: &[],
+                fn_decl,
+                body,
+                fn_decl_span: self.lower_span(span),
+                movability: Some(hir::Movability::Static),
+            });
+
+            hir::ExprKind::Closure(c)
         };
         let generator = hir::Expr {
             hir_id: self.lower_node_id(closure_node_id),
@@ -831,6 +839,7 @@ fn lower_expr_await(&mut self, dot_await_span: Span, expr: &Expr) -> hir::ExprKi
 
     fn lower_expr_closure(
         &mut self,
+        binder: &ClosureBinder,
         capture_clause: CaptureBy,
         closure_id: NodeId,
         movability: Movability,
@@ -838,7 +847,9 @@ fn lower_expr_closure(
         body: &Expr,
         fn_decl_span: Span,
     ) -> hir::ExprKind<'hir> {
-        let (body, generator_option) = self.with_new_scopes(move |this| {
+        let (binder_clause, generic_params) = self.lower_closure_binder(binder);
+
+        let (body_id, generator_option) = self.with_new_scopes(move |this| {
             let prev = this.current_item;
             this.current_item = Some(fn_decl_span);
             let mut generator_kind = None;
@@ -853,18 +864,21 @@ fn lower_expr_closure(
             (body_id, generator_option)
         });
 
-        self.with_lifetime_binder(closure_id, &[], |this, bound_generic_params| {
+        self.with_lifetime_binder(closure_id, generic_params, |this, bound_generic_params| {
             // Lower outside new scope to preserve `is_in_loop_condition`.
             let fn_decl = this.lower_fn_decl(decl, None, FnDeclKind::Closure, None);
 
-            hir::ExprKind::Closure {
+            let c = self.arena.alloc(hir::Closure {
+                binder: binder_clause,
                 capture_clause,
                 bound_generic_params,
                 fn_decl,
-                body,
+                body: body_id,
                 fn_decl_span: this.lower_span(fn_decl_span),
                 movability: generator_option,
-            }
+            });
+
+            hir::ExprKind::Closure(c)
         })
     }
 
@@ -906,8 +920,24 @@ fn generator_movability_for_fn(
         }
     }
 
+    fn lower_closure_binder<'c>(
+        &mut self,
+        binder: &'c ClosureBinder,
+    ) -> (hir::ClosureBinder, &'c [GenericParam]) {
+        let (binder, params) = match binder {
+            ClosureBinder::NotPresent => (hir::ClosureBinder::Default, &[][..]),
+            &ClosureBinder::For { span, ref generic_params } => {
+                let span = self.lower_span(span);
+                (hir::ClosureBinder::For { span }, &**generic_params)
+            }
+        };
+
+        (binder, params)
+    }
+
     fn lower_expr_async_closure(
         &mut self,
+        binder: &ClosureBinder,
         capture_clause: CaptureBy,
         closure_id: NodeId,
         inner_closure_id: NodeId,
@@ -915,6 +945,15 @@ fn lower_expr_async_closure(
         body: &Expr,
         fn_decl_span: Span,
     ) -> hir::ExprKind<'hir> {
+        if let &ClosureBinder::For { span, .. } = binder {
+            self.tcx.sess.span_err(
+                span,
+                "`for<...>` binders on `async` closures are not currently supported",
+            );
+        }
+
+        let (binder_clause, generic_params) = self.lower_closure_binder(binder);
+
         let outer_decl =
             FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
 
@@ -952,20 +991,22 @@ fn lower_expr_async_closure(
             body_id
         });
 
-        self.with_lifetime_binder(closure_id, &[], |this, bound_generic_params| {
+        self.with_lifetime_binder(closure_id, generic_params, |this, bound_generic_params| {
             // We need to lower the declaration outside the new scope, because we
             // have to conserve the state of being inside a loop condition for the
             // closure argument types.
             let fn_decl = this.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);
 
-            hir::ExprKind::Closure {
+            let c = self.arena.alloc(hir::Closure {
+                binder: binder_clause,
                 capture_clause,
                 bound_generic_params,
                 fn_decl,
                 body,
                 fn_decl_span: this.lower_span(fn_decl_span),
                 movability: None,
-            }
+            });
+            hir::ExprKind::Closure(c)
         })
     }