about summary refs log tree commit diff
path: root/compiler/rustc_mir_build/src
diff options
context:
space:
mode:
authorJakob Degen <jakob.e.degen@gmail.com>2022-04-13 07:08:58 -0400
committerJakob Degen <jakob.e.degen@gmail.com>2022-05-24 15:53:37 -0400
commit0f65bcd9204c7d4753f1747cd3559f0bc4d8150a (patch)
treec88460c22389883bdb508ab751b066acde2ff45c /compiler/rustc_mir_build/src
parent222c5724ecc922fe67815f428c19f82c129d9386 (diff)
downloadrust-0f65bcd9204c7d4753f1747cd3559f0bc4d8150a.tar.gz
rust-0f65bcd9204c7d4753f1747cd3559f0bc4d8150a.zip
Modify MIR building to drop `foo` in `[foo; 0]`
Diffstat (limited to 'compiler/rustc_mir_build/src')
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs50
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs1
2 files changed, 46 insertions, 5 deletions
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 0fd67f15b75..2f9834df9d3 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -52,11 +52,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 })
             }
             ExprKind::Repeat { value, count } => {
-                let value_operand = unpack!(
-                    block =
-                        this.as_operand(block, scope, &this.thir[value], None, NeedsTemporary::No)
-                );
-                block.and(Rvalue::Repeat(value_operand, count))
+                if Some(0) == count.try_eval_usize(this.tcx, this.param_env) {
+                    this.build_zero_repeat(block, value, scope, source_info)
+                } else {
+                    let value_operand = unpack!(
+                        block = this.as_operand(
+                            block,
+                            scope,
+                            &this.thir[value],
+                            None,
+                            NeedsTemporary::No
+                        )
+                    );
+                    block.and(Rvalue::Repeat(value_operand, count))
+                }
             }
             ExprKind::Binary { op, lhs, rhs } => {
                 let lhs = unpack!(
@@ -515,6 +524,37 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
+    fn build_zero_repeat(
+        &mut self,
+        mut block: BasicBlock,
+        value: ExprId,
+        scope: Option<region::Scope>,
+        outer_source_info: SourceInfo,
+    ) -> BlockAnd<Rvalue<'tcx>> {
+        let this = self;
+        let value = &this.thir[value];
+        let elem_ty = value.ty;
+        if let Some(Category::Constant) = Category::of(&value.kind) {
+            // Repeating a const does nothing
+        } else {
+            // For a non-const, we may need to generate an appropriate `Drop`
+            let value_operand =
+                unpack!(block = this.as_operand(block, scope, value, None, NeedsTemporary::No));
+            if let Operand::Move(to_drop) = value_operand {
+                let success = this.cfg.start_new_block();
+                this.cfg.terminate(
+                    block,
+                    outer_source_info,
+                    TerminatorKind::Drop { place: to_drop, target: success, unwind: None },
+                );
+                this.diverge_from(block);
+                block = success;
+            }
+            this.record_operands_moved(&[value_operand]);
+        }
+        block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(elem_ty)), Vec::new()))
+    }
+
     fn limit_capture_mutability(
         &mut self,
         upvar_span: Span,
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 53f9706f021..a5f8a5847c2 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -1033,6 +1033,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 self.cfg.block_data(start).terminator().kind,
                 TerminatorKind::Assert { .. }
                     | TerminatorKind::Call { .. }
+                    | TerminatorKind::Drop { .. }
                     | TerminatorKind::DropAndReplace { .. }
                     | TerminatorKind::FalseUnwind { .. }
                     | TerminatorKind::InlineAsm { .. }