Skip to content

Commit 73f5bab

Browse files
committed
rustc_mir: enforce that arguments are replaced with Local's only.
1 parent 0477319 commit 73f5bab

File tree

1 file changed

+14
-41
lines changed

1 file changed

+14
-41
lines changed

src/librustc_mir/transform/inline.rs

+14-41
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
509509
}
510510

511511
fn cast_box_free_arg(&self, arg: Lvalue<'tcx>, ptr_ty: Ty<'tcx>,
512-
callsite: &CallSite<'tcx>, caller_mir: &mut Mir<'tcx>) -> Operand<'tcx> {
512+
callsite: &CallSite<'tcx>, caller_mir: &mut Mir<'tcx>) -> Local {
513513
let arg = Rvalue::Ref(
514514
self.tcx.types.re_erased,
515515
BorrowKind::Mut,
@@ -539,25 +539,24 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
539539

540540
let cast_tmp = LocalDecl::new_temp(ptr_ty, callsite.location.span);
541541
let cast_tmp = caller_mir.local_decls.push(cast_tmp);
542-
let cast_tmp = Lvalue::Local(cast_tmp);
543542

544543
let cast_stmt = Statement {
545544
source_info: callsite.location,
546-
kind: StatementKind::Assign(cast_tmp.clone(), raw_ptr)
545+
kind: StatementKind::Assign(Lvalue::Local(cast_tmp), raw_ptr)
547546
};
548547

549548
caller_mir[callsite.bb]
550549
.statements.push(cast_stmt);
551550

552-
Operand::Consume(cast_tmp)
551+
cast_tmp
553552
}
554553

555554
fn make_call_args(
556555
&self,
557556
args: Vec<Operand<'tcx>>,
558557
callsite: &CallSite<'tcx>,
559558
caller_mir: &mut Mir<'tcx>,
560-
) -> Vec<Operand<'tcx>> {
559+
) -> Vec<Local> {
561560
let tcx = self.tcx;
562561

563562
// There is a bit of a mismatch between the *caller* of a closure and the *callee*.
@@ -589,14 +588,15 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
589588
let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_mir);
590589
assert!(args.next().is_none());
591590

591+
let tuple = Lvalue::Local(tuple);
592592
let tuple_tys = if let ty::TyTuple(s, _) = tuple.ty(caller_mir, tcx).to_ty(tcx).sty {
593593
s
594594
} else {
595595
bug!("Closure arguments are not passed as a tuple");
596596
};
597597

598598
// The `closure_ref` in our example above.
599-
let closure_ref_arg = iter::once(Operand::Consume(self_));
599+
let closure_ref_arg = iter::once(self_);
600600

601601
// The `tmp0`, `tmp1`, and `tmp2` in our example abonve.
602602
let tuple_tmp_args =
@@ -605,14 +605,13 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
605605
let tuple_field = Operand::Consume(tuple.clone().field(Field::new(i), ty));
606606

607607
// Spill to a local to make e.g. `tmp0`.
608-
let tmp = self.create_temp_if_necessary(tuple_field, callsite, caller_mir);
609-
Operand::Consume(tmp)
608+
self.create_temp_if_necessary(tuple_field, callsite, caller_mir)
610609
});
611610

612611
closure_ref_arg.chain(tuple_tmp_args).collect()
613612
} else {
614613
args.into_iter()
615-
.map(|a| Operand::Consume(self.create_temp_if_necessary(a, callsite, caller_mir)))
614+
.map(|a| self.create_temp_if_necessary(a, callsite, caller_mir))
616615
.collect()
617616
}
618617
}
@@ -624,14 +623,14 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
624623
arg: Operand<'tcx>,
625624
callsite: &CallSite<'tcx>,
626625
caller_mir: &mut Mir<'tcx>,
627-
) -> Lvalue<'tcx> {
626+
) -> Local {
628627
// FIXME: Analysis of the usage of the arguments to avoid
629628
// unnecessary temporaries.
630629

631630
if let Operand::Consume(Lvalue::Local(local)) = arg {
632631
if caller_mir.local_kind(local) == LocalKind::Temp {
633632
// Reuse the operand if it's a temporary already
634-
return Lvalue::Local(local);
633+
return local;
635634
}
636635
}
637636

@@ -643,11 +642,10 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
643642

644643
let arg_tmp = LocalDecl::new_temp(ty, callsite.location.span);
645644
let arg_tmp = caller_mir.local_decls.push(arg_tmp);
646-
let arg_tmp = Lvalue::Local(arg_tmp);
647645

648646
let stmt = Statement {
649647
source_info: callsite.location,
650-
kind: StatementKind::Assign(arg_tmp.clone(), arg),
648+
kind: StatementKind::Assign(Lvalue::Local(arg_tmp), arg),
651649
};
652650
caller_mir[callsite.bb].statements.push(stmt);
653651
arg_tmp
@@ -693,7 +691,7 @@ fn subst_and_normalize<'a, 'tcx: 'a>(
693691
*/
694692
struct Integrator<'a, 'tcx: 'a> {
695693
block_idx: usize,
696-
args: &'a [Operand<'tcx>],
694+
args: &'a [Local],
697695
local_map: IndexVec<Local, Local>,
698696
scope_map: IndexVec<VisibilityScope, VisibilityScope>,
699697
promoted_map: IndexVec<Promoted, Promoted>,
@@ -710,15 +708,6 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> {
710708
debug!("Updating target `{:?}`, new: `{:?}`", tgt, new);
711709
new
712710
}
713-
714-
fn arg_index(&self, arg: Local) -> Option<usize> {
715-
let idx = arg.index();
716-
if idx > 0 && idx <= self.args.len() {
717-
Some(idx - 1)
718-
} else {
719-
None
720-
}
721-
}
722711
}
723712

724713
impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
@@ -737,13 +726,8 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
737726
}
738727
let idx = local.index() - 1;
739728
if idx < self.args.len() {
740-
match self.args[idx] {
741-
Operand::Consume(Lvalue::Local(l)) => {
742-
*local = l;
743-
return;
744-
},
745-
ref op => bug!("Arg operand `{:?}` is {:?}, not local", idx, op)
746-
}
729+
*local = self.args[idx];
730+
return;
747731
}
748732
*local = self.local_map[Local::new(idx - self.args.len())];
749733
}
@@ -760,17 +744,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
760744
}
761745
}
762746

763-
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) {
764-
if let Operand::Consume(Lvalue::Local(arg)) = *operand {
765-
if let Some(idx) = self.arg_index(arg) {
766-
let new_arg = self.args[idx].clone();
767-
*operand = new_arg;
768-
return;
769-
}
770-
}
771-
self.super_operand(operand, location);
772-
}
773-
774747
fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) {
775748
self.in_cleanup_block = data.is_cleanup;
776749
self.super_basic_block_data(block, data);

0 commit comments

Comments
 (0)