Skip to content

Commit 2f1ef9e

Browse files
committed
Auto merge of #44308 - eddyb:local-index, r=arielb1
[MIR] Restrict ProjectionElem::Index and Storage{Live,Dead} to Local. (see #44285) r? @nikomatsakis
2 parents 2f681bf + e74f96e commit 2f1ef9e

27 files changed

+319
-362
lines changed

src/librustc/mir/mod.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -901,10 +901,10 @@ pub enum StatementKind<'tcx> {
901901
SetDiscriminant { lvalue: Lvalue<'tcx>, variant_index: usize },
902902

903903
/// Start a live range for the storage of the local.
904-
StorageLive(Lvalue<'tcx>),
904+
StorageLive(Local),
905905

906906
/// End the current live range for the storage of the local.
907-
StorageDead(Lvalue<'tcx>),
907+
StorageDead(Local),
908908

909909
/// Execute a piece of inline Assembly.
910910
InlineAsm {
@@ -1077,12 +1077,12 @@ pub enum ProjectionElem<'tcx, V, T> {
10771077
}
10781078

10791079
/// Alias for projections as they appear in lvalues, where the base is an lvalue
1080-
/// and the index is an operand.
1081-
pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Operand<'tcx>, Ty<'tcx>>;
1080+
/// and the index is a local.
1081+
pub type LvalueProjection<'tcx> = Projection<'tcx, Lvalue<'tcx>, Local, Ty<'tcx>>;
10821082

10831083
/// Alias for projections as they appear in lvalues, where the base is an lvalue
1084-
/// and the index is an operand.
1085-
pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Operand<'tcx>, Ty<'tcx>>;
1084+
/// and the index is a local.
1085+
pub type LvalueElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>;
10861086

10871087
newtype_index!(Field, "field");
10881088

@@ -1099,7 +1099,7 @@ impl<'tcx> Lvalue<'tcx> {
10991099
self.elem(ProjectionElem::Downcast(adt_def, variant_index))
11001100
}
11011101

1102-
pub fn index(self, index: Operand<'tcx>) -> Lvalue<'tcx> {
1102+
pub fn index(self, index: Local) -> Lvalue<'tcx> {
11031103
self.elem(ProjectionElem::Index(index))
11041104
}
11051105

@@ -1701,8 +1701,8 @@ impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
17011701
lvalue: lvalue.fold_with(folder),
17021702
variant_index,
17031703
},
1704-
StorageLive(ref lval) => StorageLive(lval.fold_with(folder)),
1705-
StorageDead(ref lval) => StorageDead(lval.fold_with(folder)),
1704+
StorageLive(ref local) => StorageLive(local.fold_with(folder)),
1705+
StorageDead(ref local) => StorageDead(local.fold_with(folder)),
17061706
InlineAsm { ref asm, ref outputs, ref inputs } => InlineAsm {
17071707
asm: asm.clone(),
17081708
outputs: outputs.fold_with(folder),
@@ -1732,9 +1732,9 @@ impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
17321732

17331733
match self.kind {
17341734
Assign(ref lval, ref rval) => { lval.visit_with(visitor) || rval.visit_with(visitor) }
1735-
SetDiscriminant { ref lvalue, .. } |
1736-
StorageLive(ref lvalue) |
1737-
StorageDead(ref lvalue) => lvalue.visit_with(visitor),
1735+
SetDiscriminant { ref lvalue, .. } => lvalue.visit_with(visitor),
1736+
StorageLive(ref local) |
1737+
StorageDead(ref local) => local.visit_with(visitor),
17381738
InlineAsm { ref outputs, ref inputs, .. } =>
17391739
outputs.visit_with(visitor) || inputs.visit_with(visitor),
17401740

src/librustc/mir/visit.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,9 @@ macro_rules! make_mir_visitor {
256256
}
257257

258258
fn visit_local(&mut self,
259-
_local: & $($mutability)* Local) {
259+
_local: & $($mutability)* Local,
260+
_context: LvalueContext<'tcx>,
261+
_location: Location) {
260262
}
261263

262264
fn visit_visibility_scope(&mut self,
@@ -358,11 +360,11 @@ macro_rules! make_mir_visitor {
358360
StatementKind::SetDiscriminant{ ref $($mutability)* lvalue, .. } => {
359361
self.visit_lvalue(lvalue, LvalueContext::Store, location);
360362
}
361-
StatementKind::StorageLive(ref $($mutability)* lvalue) => {
362-
self.visit_lvalue(lvalue, LvalueContext::StorageLive, location);
363+
StatementKind::StorageLive(ref $($mutability)* local) => {
364+
self.visit_local(local, LvalueContext::StorageLive, location);
363365
}
364-
StatementKind::StorageDead(ref $($mutability)* lvalue) => {
365-
self.visit_lvalue(lvalue, LvalueContext::StorageDead, location);
366+
StatementKind::StorageDead(ref $($mutability)* local) => {
367+
self.visit_local(local, LvalueContext::StorageDead, location);
366368
}
367369
StatementKind::InlineAsm { ref $($mutability)* outputs,
368370
ref $($mutability)* inputs,
@@ -610,7 +612,7 @@ macro_rules! make_mir_visitor {
610612
location: Location) {
611613
match *lvalue {
612614
Lvalue::Local(ref $($mutability)* local) => {
613-
self.visit_local(local);
615+
self.visit_local(local, context, location);
614616
}
615617
Lvalue::Static(ref $($mutability)* static_) => {
616618
self.visit_static(static_, context, location);
@@ -662,8 +664,8 @@ macro_rules! make_mir_visitor {
662664
ProjectionElem::Field(_field, ref $($mutability)* ty) => {
663665
self.visit_ty(ty, Lookup::Loc(location));
664666
}
665-
ProjectionElem::Index(ref $($mutability)* operand) => {
666-
self.visit_operand(operand, location);
667+
ProjectionElem::Index(ref $($mutability)* local) => {
668+
self.visit_local(local, LvalueContext::Consume, location);
667669
}
668670
ProjectionElem::ConstantIndex { offset: _,
669671
min_length: _,

src/librustc/ty/structural_impls.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ macro_rules! CopyImpls {
421421
}
422422
}
423423

424-
CopyImpls! { (), hir::Unsafety, abi::Abi, hir::def_id::DefId }
424+
CopyImpls! { (), hir::Unsafety, abi::Abi, hir::def_id::DefId, ::mir::Local }
425425

426426
impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
427427
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {

src/librustc_mir/borrow_check.rs

+6-23
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,11 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> DataflowResultsConsumer<'b, 'gcx>
212212
// ignored by borrowck
213213
}
214214

215-
StatementKind::StorageDead(ref lvalue) => {
215+
StatementKind::StorageDead(local) => {
216216
// causes non-drop values to be dropped.
217217
self.consume_lvalue(ContextKind::StorageDead.new(location),
218218
ConsumeKind::Consume,
219-
(lvalue, span),
219+
(&Lvalue::Local(local), span),
220220
flow_state)
221221
}
222222
}
@@ -710,7 +710,7 @@ mod restrictions {
710710

711711
use rustc::hir;
712712
use rustc::ty::{self, TyCtxt};
713-
use rustc::mir::{Lvalue, Mir, Operand, ProjectionElem};
713+
use rustc::mir::{Lvalue, Mir, ProjectionElem};
714714

715715
pub(super) struct Restrictions<'c, 'tcx: 'c> {
716716
mir: &'c Mir<'tcx>,
@@ -809,12 +809,7 @@ mod restrictions {
809809
ProjectionElem::Downcast(..) |
810810
ProjectionElem::Subslice { .. } |
811811
ProjectionElem::ConstantIndex { .. } |
812-
ProjectionElem::Index(Operand::Constant(..)) => {
813-
cursor = &proj.base;
814-
continue 'cursor;
815-
}
816-
ProjectionElem::Index(Operand::Consume(ref index)) => {
817-
self.lvalue_stack.push(index); // FIXME: did old borrowck do this?
812+
ProjectionElem::Index(_) => {
818813
cursor = &proj.base;
819814
continue 'cursor;
820815
}
@@ -1004,7 +999,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
1004999
("", format!(""), None), // (dont emit downcast info)
10051000
ProjectionElem::Field(field, _ty) =>
10061001
("", format!(".{}", field.index()), None),
1007-
ProjectionElem::Index(ref index) =>
1002+
ProjectionElem::Index(index) =>
10081003
("", format!(""), Some(index)),
10091004
ProjectionElem::ConstantIndex { offset, min_length, from_end: true } =>
10101005
("", format!("[{} of {}]", offset, min_length), None),
@@ -1021,23 +1016,11 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
10211016
self.append_lvalue_to_string(&proj.base, buf);
10221017
if let Some(index) = index_operand {
10231018
buf.push_str("[");
1024-
self.append_operand_to_string(index, buf);
1019+
self.append_lvalue_to_string(&Lvalue::Local(index), buf);
10251020
buf.push_str("]");
10261021
} else {
10271022
buf.push_str(&suffix);
10281023
}
1029-
1030-
}
1031-
}
1032-
}
1033-
1034-
fn append_operand_to_string(&self, operand: &Operand, buf: &mut String) {
1035-
match *operand {
1036-
Operand::Consume(ref lvalue) => {
1037-
self.append_lvalue_to_string(lvalue, buf);
1038-
}
1039-
Operand::Constant(ref constant) => {
1040-
buf.push_str(&format!("{:?}", constant));
10411024
}
10421025
}
10431026
}

src/librustc_mir/build/expr/as_lvalue.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
6161
// region_scope=None so lvalue indexes live forever. They are scalars so they
6262
// do not need storage annotations, and they are often copied between
6363
// places.
64-
let idx = unpack!(block = this.as_operand(block, None, index));
64+
let idx = unpack!(block = this.as_temp(block, None, index));
6565

6666
// bounds check:
6767
let (len, lt) = (this.temp(usize_ty.clone(), expr_span),
@@ -70,12 +70,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
7070
&len, Rvalue::Len(slice.clone()));
7171
this.cfg.push_assign(block, source_info, // lt = idx < len
7272
&lt, Rvalue::BinaryOp(BinOp::Lt,
73-
idx.clone(),
73+
Operand::Consume(Lvalue::Local(idx)),
7474
Operand::Consume(len.clone())));
7575

7676
let msg = AssertMessage::BoundsCheck {
7777
len: Operand::Consume(len),
78-
index: idx.clone()
78+
index: Operand::Consume(Lvalue::Local(idx))
7979
};
8080
let success = this.assert(block, Operand::Consume(lt), true,
8181
msg, expr_span);
@@ -127,7 +127,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
127127
Some(Category::Lvalue) => false,
128128
_ => true,
129129
});
130-
this.as_temp(block, expr.temp_lifetime, expr)
130+
let temp = unpack!(block = this.as_temp(block, expr.temp_lifetime, expr));
131+
block.and(Lvalue::Local(temp))
131132
}
132133
}
133134
}

src/librustc_mir/build/expr/as_operand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
7474
Category::Rvalue(..) => {
7575
let operand =
7676
unpack!(block = this.as_temp(block, scope, expr));
77-
block.and(Operand::Consume(operand))
77+
block.and(Operand::Consume(Lvalue::Local(operand)))
7878
}
7979
}
8080
}

src/librustc_mir/build/expr/as_rvalue.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -96,23 +96,23 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
9696
}
9797
ExprKind::Box { value } => {
9898
let value = this.hir.mirror(value);
99-
let result = this.temp(expr.ty, expr_span);
99+
let result = this.local_decls.push(LocalDecl::new_temp(expr.ty, expr_span));
100100
this.cfg.push(block, Statement {
101101
source_info,
102-
kind: StatementKind::StorageLive(result.clone())
102+
kind: StatementKind::StorageLive(result)
103103
});
104104
if let Some(scope) = scope {
105105
// schedule a shallow free of that memory, lest we unwind:
106-
this.schedule_drop(expr_span, scope, &result, value.ty);
106+
this.schedule_drop(expr_span, scope, &Lvalue::Local(result), value.ty);
107107
}
108108

109109
// malloc some memory of suitable type (thus far, uninitialized):
110110
let box_ = Rvalue::NullaryOp(NullOp::Box, value.ty);
111-
this.cfg.push_assign(block, source_info, &result, box_);
111+
this.cfg.push_assign(block, source_info, &Lvalue::Local(result), box_);
112112

113113
// initialize the box contents:
114-
unpack!(block = this.into(&result.clone().deref(), block, value));
115-
block.and(Rvalue::Use(Operand::Consume(result)))
114+
unpack!(block = this.into(&Lvalue::Local(result).deref(), block, value));
115+
block.and(Rvalue::Use(Operand::Consume(Lvalue::Local(result))))
116116
}
117117
ExprKind::Cast { source } => {
118118
let source = this.hir.mirror(source);

src/librustc_mir/build/expr/as_temp.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
2323
block: BasicBlock,
2424
temp_lifetime: Option<region::Scope>,
2525
expr: M)
26-
-> BlockAnd<Lvalue<'tcx>>
26+
-> BlockAnd<Local>
2727
where M: Mirror<'tcx, Output = Expr<'tcx>>
2828
{
2929
let expr = self.hir.mirror(expr);
@@ -34,7 +34,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
3434
mut block: BasicBlock,
3535
temp_lifetime: Option<region::Scope>,
3636
expr: Expr<'tcx>)
37-
-> BlockAnd<Lvalue<'tcx>> {
37+
-> BlockAnd<Local> {
3838
debug!("expr_as_temp(block={:?}, temp_lifetime={:?}, expr={:?})",
3939
block, temp_lifetime, expr);
4040
let this = self;
@@ -47,13 +47,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
4747
});
4848
}
4949

50-
let expr_ty = expr.ty.clone();
51-
let temp = this.temp(expr_ty.clone(), expr_span);
50+
let expr_ty = expr.ty;
51+
let temp = this.local_decls.push(LocalDecl::new_temp(expr_ty, expr_span));
5252

5353
if !expr_ty.is_never() {
5454
this.cfg.push(block, Statement {
5555
source_info,
56-
kind: StatementKind::StorageLive(temp.clone())
56+
kind: StatementKind::StorageLive(temp)
5757
});
5858
}
5959

@@ -68,18 +68,18 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
6868
Category::Lvalue => {
6969
let lvalue = unpack!(block = this.as_lvalue(block, expr));
7070
let rvalue = Rvalue::Use(Operand::Consume(lvalue));
71-
this.cfg.push_assign(block, source_info, &temp, rvalue);
71+
this.cfg.push_assign(block, source_info, &Lvalue::Local(temp), rvalue);
7272
}
7373
_ => {
74-
unpack!(block = this.into(&temp, block, expr));
74+
unpack!(block = this.into(&Lvalue::Local(temp), block, expr));
7575
}
7676
}
7777

7878
// In constants, temp_lifetime is None. We should not need to drop
7979
// anything because no values with a destructor can be created in
8080
// a constant at this time, even if the type may need dropping.
8181
if let Some(temp_lifetime) = temp_lifetime {
82-
this.schedule_drop(expr_span, temp_lifetime, &temp, expr_ty);
82+
this.schedule_drop(expr_span, temp_lifetime, &Lvalue::Local(temp), expr_ty);
8383
}
8484

8585
block.and(temp)

src/librustc_mir/build/expr/into.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
229229

230230
let topmost_scope = this.topmost_scope();
231231
let ptr = unpack!(block = this.as_temp(block, Some(topmost_scope), ptr));
232-
this.into(&ptr.deref(), block, val)
232+
this.into(&Lvalue::Local(ptr).deref(), block, val)
233233
} else {
234234
let args: Vec<_> =
235235
args.into_iter()

src/librustc_mir/build/matches/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
194194
let source_info = self.source_info(span);
195195
self.cfg.push(block, Statement {
196196
source_info,
197-
kind: StatementKind::StorageLive(Lvalue::Local(local_id))
197+
kind: StatementKind::StorageLive(local_id)
198198
});
199199
Lvalue::Local(local_id)
200200
}

src/librustc_mir/build/scope.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>,
822822
Lvalue::Local(index) if index.index() > arg_count => {
823823
cfg.push(block, Statement {
824824
source_info,
825-
kind: StatementKind::StorageDead(drop_data.location.clone())
825+
kind: StatementKind::StorageDead(index)
826826
});
827827
}
828828
_ => continue

src/librustc_mir/dataflow/move_paths/abs_domain.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
//! `a[x]` would still overlap them both. But that is not this
2222
//! representation does today.)
2323
24-
use rustc::mir::LvalueElem;
25-
use rustc::mir::{Operand, ProjectionElem};
24+
use rustc::mir::{Local, LvalueElem, Operand, ProjectionElem};
2625
use rustc::ty::Ty;
2726

2827
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -40,6 +39,10 @@ impl<'tcx> Lift for Operand<'tcx> {
4039
type Abstract = AbstractOperand;
4140
fn lift(&self) -> Self::Abstract { AbstractOperand }
4241
}
42+
impl Lift for Local {
43+
type Abstract = AbstractOperand;
44+
fn lift(&self) -> Self::Abstract { AbstractOperand }
45+
}
4346
impl<'tcx> Lift for Ty<'tcx> {
4447
type Abstract = AbstractType;
4548
fn lift(&self) -> Self::Abstract { AbstractType }

0 commit comments

Comments
 (0)