]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
Also generate `StorageDead` in constants
[rust.git] / compiler / rustc_mir_build / src / build / expr / as_rvalue.rs
index 7c34b996055d3e214f4091b9324fdf2c566b85fa..6537ba745c17a66954fa05465ac8168f251862db 100644 (file)
@@ -11,6 +11,8 @@
 use rustc_middle::ty::{self, Ty, UpvarSubsts};
 use rustc_span::Span;
 
+use std::slice;
+
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Returns an rvalue suitable for use until the end of the current
     /// scope expression.
@@ -23,7 +25,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         M: Mirror<'tcx, Output = Expr<'tcx>>,
     {
         let local_scope = self.local_scope();
-        self.as_rvalue(block, local_scope, expr)
+        self.as_rvalue(block, Some(local_scope), expr)
     }
 
     /// Compile `expr`, yielding an rvalue.
@@ -112,12 +114,19 @@ fn expr_as_rvalue(
                 let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
                 this.cfg.push_assign(block, source_info, Place::from(result), box_);
 
-                // initialize the box contents:
+                // Initialize the box contents. No scope is needed since the
+                // `Box` is already scheduled to be dropped.
                 unpack!(
-                    block =
-                        this.into(this.hir.tcx().mk_place_deref(Place::from(result)), block, value)
+                    block = this.into(
+                        this.hir.tcx().mk_place_deref(Place::from(result)),
+                        None,
+                        block,
+                        value,
+                    )
                 );
-                block.and(Rvalue::Use(Operand::Move(Place::from(result))))
+                let result_operand = Operand::Move(Place::from(result));
+                this.record_operands_moved(slice::from_ref(&result_operand));
+                block.and(Rvalue::Use(result_operand))
             }
             ExprKind::Cast { source } => {
                 let source = unpack!(block = this.as_operand(block, scope, source));
@@ -161,6 +170,7 @@ fn expr_as_rvalue(
                     .map(|f| unpack!(block = this.as_operand(block, scope, f)))
                     .collect();
 
+                this.record_operands_moved(&fields);
                 block.and(Rvalue::Aggregate(box AggregateKind::Array(el_ty), fields))
             }
             ExprKind::Tuple { fields } => {
@@ -171,6 +181,7 @@ fn expr_as_rvalue(
                     .map(|f| unpack!(block = this.as_operand(block, scope, f)))
                     .collect();
 
+                this.record_operands_moved(&fields);
                 block.and(Rvalue::Aggregate(box AggregateKind::Tuple, fields))
             }
             ExprKind::Closure { closure_id, substs, upvars, movability } => {
@@ -222,6 +233,7 @@ fn expr_as_rvalue(
                     }
                     UpvarSubsts::Closure(substs) => box AggregateKind::Closure(closure_id, substs),
                 };
+                this.record_operands_moved(&operands);
                 block.and(Rvalue::Aggregate(result, operands))
             }
             ExprKind::Assign { .. } | ExprKind::AssignOp { .. } => {
@@ -433,9 +445,8 @@ fn limit_capture_mutability(
             Rvalue::Ref(this.hir.tcx().lifetimes.re_erased, borrow_kind, arg_place),
         );
 
-        // In constants, temp_lifetime is None. We should not need to drop
-        // anything because no values with a destructor can be created in
-        // a constant at this time, even if the type may need dropping.
+        // See the comment in `expr_as_temp` and on the `rvalue_scopes` field for why
+        // this can be `None`.
         if let Some(temp_lifetime) = temp_lifetime {
             this.schedule_drop_storage_and_value(upvar_span, temp_lifetime, temp);
         }