diff options
| author | Jakob Degen <jakob.e.degen@gmail.com> | 2022-04-13 07:08:58 -0400 |
|---|---|---|
| committer | Jakob Degen <jakob.e.degen@gmail.com> | 2022-05-24 15:53:37 -0400 |
| commit | 0f65bcd9204c7d4753f1747cd3559f0bc4d8150a (patch) | |
| tree | c88460c22389883bdb508ab751b066acde2ff45c /compiler/rustc_mir_build/src | |
| parent | 222c5724ecc922fe67815f428c19f82c129d9386 (diff) | |
| download | rust-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.rs | 50 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/build/scope.rs | 1 |
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 { .. } |
