Skip to content

Commit 8eaf782

Browse files
committed
Make PlaceElem::Index take a Place.
1 parent b1691f6 commit 8eaf782

File tree

16 files changed

+80
-63
lines changed

16 files changed

+80
-63
lines changed

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub(crate) use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionError
4646
pub(crate) use region_name::{RegionName, RegionNameSource};
4747
pub(crate) use rustc_const_eval::util::CallKind;
4848

49+
#[derive(Copy, Clone)]
4950
pub(super) struct DescribePlaceOpt {
5051
pub including_downcast: bool,
5152

@@ -265,7 +266,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
265266
}
266267
ProjectionElem::Index(index) => {
267268
buf.push('[');
268-
if self.append_local_to_string(*index, &mut buf).is_err() {
269+
if let Some(index) = self.describe_place_with_options(index.as_ref(), opt) {
270+
buf.push_str(&index);
271+
} else {
269272
buf.push('_');
270273
}
271274
buf.push(']');

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -851,8 +851,8 @@ pub(crate) fn codegen_place<'tcx>(
851851
PlaceElem::Field(field, _ty) => {
852852
cplace = cplace.place_field(fx, field);
853853
}
854-
PlaceElem::Index(local) => {
855-
let index = fx.get_local_place(local).to_cvalue(fx).load_scalar(fx);
854+
PlaceElem::Index(index) => {
855+
let index = codegen_place(fx, index).to_cvalue(fx).load_scalar(fx);
856856
cplace = cplace.place_index(fx, index);
857857
}
858858
PlaceElem::ConstantIndex { offset, min_length: _, from_end } => {

compiler/rustc_codegen_ssa/src/mir/analyze.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,9 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx,
141141
// HACK(eddyb) this emulates the old `visit_projection_elem`, this
142142
// entire `visit_place`-like `process_place` method should be rewritten,
143143
// now that we have moved to the "slice of projections" representation.
144-
if let mir::ProjectionElem::Index(local) = elem {
145-
self.visit_local(
146-
local,
144+
if let mir::ProjectionElem::Index(ref index) = elem {
145+
self.visit_place(
146+
index,
147147
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
148148
location,
149149
);

compiler/rustc_const_eval/src/interpret/projection.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,9 @@ where
360360
Field(field, _) => self.place_field(base, field.index())?,
361361
Downcast(_, variant) => self.place_downcast(base, variant)?,
362362
Deref => self.deref_operand(&self.place_to_op(base)?)?.into(),
363-
Index(local) => {
363+
Index(place) => {
364364
let layout = self.layout_of(self.tcx.types.usize)?;
365-
let n = self.local_to_op(self.frame(), local, Some(layout))?;
365+
let n = self.eval_place_to_op(place, Some(layout))?;
366366
let n = self.read_machine_usize(&n)?;
367367
self.place_index(base, n)?
368368
}
@@ -389,9 +389,9 @@ where
389389
Field(field, _) => self.operand_field(base, field.index())?,
390390
Downcast(_, variant) => self.operand_downcast(base, variant)?,
391391
Deref => self.deref_operand(base)?.into(),
392-
Index(local) => {
392+
Index(place) => {
393393
let layout = self.layout_of(self.tcx.types.usize)?;
394-
let n = self.local_to_op(self.frame(), local, Some(layout))?;
394+
let n = self.eval_place_to_op(place, Some(layout))?;
395395
let n = self.read_machine_usize(&n)?;
396396
self.operand_index(base, n)?
397397
}

compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,9 @@ where
298298
let mut place = place;
299299
while let Some((place_base, elem)) = place.last_projection() {
300300
match elem {
301-
ProjectionElem::Index(index) if in_local(index) => return true,
301+
ProjectionElem::Index(index) if in_place::<Q, _>(cx, in_local, index.as_ref()) => {
302+
return true;
303+
}
302304

303305
ProjectionElem::Deref
304306
| ProjectionElem::Field(_, _)

compiler/rustc_const_eval/src/transform/promote_consts.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -361,27 +361,28 @@ impl<'tcx> Validator<'_, 'tcx> {
361361

362362
ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {}
363363

364-
ProjectionElem::Index(local) => {
364+
ProjectionElem::Index(place) => {
365365
let mut promotable = false;
366366
// Only accept if we can predict the index and are indexing an array.
367-
let val =
368-
if let TempState::Defined { location: loc, .. } = self.temps[local] {
369-
let block = &self.body[loc.block];
370-
if loc.statement_index < block.statements.len() {
371-
let statement = &block.statements[loc.statement_index];
372-
match &statement.kind {
373-
StatementKind::Assign(box (
374-
_,
375-
Rvalue::Use(Operand::Constant(c)),
376-
)) => c.literal.try_eval_usize(self.tcx, self.param_env),
377-
_ => None,
378-
}
379-
} else {
380-
None
367+
let val = if let Some(local) = place.as_local()
368+
&& let TempState::Defined { location: loc, .. } = self.temps[local]
369+
{
370+
let block = &self.body[loc.block];
371+
if loc.statement_index < block.statements.len() {
372+
let statement = &block.statements[loc.statement_index];
373+
match &statement.kind {
374+
StatementKind::Assign(box (
375+
_,
376+
Rvalue::Use(Operand::Constant(c)),
377+
)) => c.literal.try_eval_usize(self.tcx, self.param_env),
378+
_ => None,
381379
}
382380
} else {
383381
None
384-
};
382+
}
383+
} else {
384+
None
385+
};
385386
if let Some(idx) = val {
386387
// Determine the type of the thing we are indexing.
387388
let ty = place_base.ty(self.body, self.tcx).ty;
@@ -403,7 +404,7 @@ impl<'tcx> Validator<'_, 'tcx> {
403404
return Err(Unpromotable);
404405
}
405406

406-
self.validate_local(local)?;
407+
self.validate_place(place.as_ref())?;
407408
}
408409

409410
ProjectionElem::Field(..) => {

compiler/rustc_const_eval/src/transform/validate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
204204
location: Location,
205205
) {
206206
match elem {
207-
ProjectionElem::Index(index) => {
208-
let index_ty = self.body.local_decls[index].ty;
207+
ProjectionElem::Index(ref index) => {
208+
let index_ty = Place::ty(index, &self.body.local_decls, self.tcx).ty;
209209
if index_ty != self.tcx.types.usize {
210210
self.fail(location, format!("bad index ({:?} != usize)", index_ty))
211211
}

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ pub enum ProjectionElem<V, T> {
956956

957957
/// Alias for projections as they appear in places, where the base is a place
958958
/// and the index is a local.
959-
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
959+
pub type PlaceElem<'tcx> = ProjectionElem<Place<'tcx>, Ty<'tcx>>;
960960

961961
///////////////////////////////////////////////////////////////////////////
962962
// Operands

compiler/rustc_middle/src/mir/visit.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,15 +1078,15 @@ macro_rules! visit_place_fns {
10781078
location: Location,
10791079
) -> Option<PlaceElem<'tcx>> {
10801080
match elem {
1081-
PlaceElem::Index(local) => {
1082-
let mut new_local = local;
1083-
self.visit_local(
1084-
&mut new_local,
1081+
PlaceElem::Index(place) => {
1082+
let mut new_place = place;
1083+
self.visit_place(
1084+
&mut new_place,
10851085
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
10861086
location,
10871087
);
10881088

1089-
if new_local == local { None } else { Some(PlaceElem::Index(new_local)) }
1089+
if new_place == place { None } else { Some(PlaceElem::Index(new_place)) }
10901090
}
10911091
PlaceElem::Field(field, ty) => {
10921092
let mut new_ty = ty;
@@ -1170,9 +1170,9 @@ macro_rules! visit_place_fns {
11701170
ProjectionElem::OpaqueCast(ty) | ProjectionElem::Field(_, ty) => {
11711171
self.visit_ty(ty, TyContext::Location(location));
11721172
}
1173-
ProjectionElem::Index(local) => {
1174-
self.visit_local(
1175-
local,
1173+
ProjectionElem::Index(ref place) => {
1174+
self.visit_place(
1175+
place,
11761176
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
11771177
location,
11781178
);

compiler/rustc_middle/src/ty/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2048,7 +2048,7 @@ impl<'tcx> TyCtxt<'tcx> {
20482048
}
20492049

20502050
pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> {
2051-
self.mk_place_elem(place, PlaceElem::Index(index))
2051+
self.mk_place_elem(place, PlaceElem::Index(index.into()))
20522052
}
20532053

20542054
/// This method copies `Place`'s projection, add an element and reintern it. Should not be used

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
190190
_ => (*arg, PlaceElem::Deref),
191191
)
192192
},
193-
ExprKind::Index { lhs, index } => (*lhs, PlaceElem::Index(self.parse_local(*index)?)),
193+
ExprKind::Index { lhs, index } => (*lhs, PlaceElem::Index(self.parse_place(*index)?)),
194194
ExprKind::Field { lhs, name: field, .. } => (*lhs, PlaceElem::Field(*field, expr.ty)),
195195
_ => {
196196
let place = self.parse_local(expr_id).map(Place::from)?;

compiler/rustc_mir_build/src/build/expr/as_place.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
308308
}
309309

310310
fn index(self, index: Local) -> Self {
311-
self.project(PlaceElem::Index(index))
311+
self.project(PlaceElem::Index(index.into()))
312312
}
313313

314314
pub(crate) fn project(mut self, elem: PlaceElem<'tcx>) -> Self {

compiler/rustc_mir_dataflow/src/move_paths/abs_domain.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! `a[x]` would still overlap them both. But that is not this
1212
//! representation does today.)
1313
14-
use rustc_middle::mir::{Local, Operand, PlaceElem, ProjectionElem};
14+
use rustc_middle::mir::{Local, Operand, Place, PlaceElem, ProjectionElem};
1515
use rustc_middle::ty::Ty;
1616

1717
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -36,6 +36,12 @@ impl Lift for Local {
3636
AbstractOperand
3737
}
3838
}
39+
impl<'tcx> Lift for Place<'tcx> {
40+
type Abstract = AbstractOperand;
41+
fn lift(&self) -> Self::Abstract {
42+
AbstractOperand
43+
}
44+
}
3945
impl<'tcx> Lift for Ty<'tcx> {
4046
type Abstract = AbstractType;
4147
fn lift(&self) -> Self::Abstract {

compiler/rustc_mir_transform/src/generator.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> {
128128
self.tcx,
129129
);
130130
} else {
131-
self.visit_local(&mut place.local, context, location);
132-
133-
for elem in place.projection.iter() {
134-
if let PlaceElem::Index(local) = elem {
135-
assert_ne!(local, SELF_ARG);
136-
}
137-
}
131+
self.super_place(place, context, location);
138132
}
139133
}
140134
}
@@ -167,13 +161,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
167161
self.tcx,
168162
);
169163
} else {
170-
self.visit_local(&mut place.local, context, location);
171-
172-
for elem in place.projection.iter() {
173-
if let PlaceElem::Index(local) = elem {
174-
assert_ne!(local, SELF_ARG);
175-
}
176-
}
164+
self.super_place(place, context, location);
177165
}
178166
}
179167
}

compiler/rustc_mir_transform/src/inline.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,12 +1054,6 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> {
10541054
}
10551055

10561056
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
1057-
for elem in place.projection {
1058-
// FIXME: Make sure that return place is not used in an indexing projection, since it
1059-
// won't be rebased as it is supposed to be.
1060-
assert_ne!(ProjectionElem::Index(RETURN_PLACE), elem);
1061-
}
1062-
10631057
// If this is the `RETURN_PLACE`, we need to rebase any projections onto it.
10641058
let dest_proj_len = self.destination.projection.len();
10651059
if place.local == RETURN_PLACE && dest_proj_len > 0 {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
pub fn outer() -> usize {
2+
inner()
3+
}
4+
5+
fn index() -> usize {
6+
loop {}
7+
}
8+
9+
#[inline]
10+
fn inner() -> usize {
11+
let buffer = &[true];
12+
let index = index();
13+
// DestProp may unify `index` with `_0`. Check that inlining does not ICE.
14+
if buffer[index] {
15+
index
16+
} else {
17+
0
18+
}
19+
}
20+
21+
fn main() {
22+
let _ = outer();
23+
}

0 commit comments

Comments
 (0)