Skip to content

Commit b31ab07

Browse files
committed
Implement ConstantIndex handling and use that instead using our own ProjectionElem variant
1 parent 7ad6b33 commit b31ab07

File tree

1 file changed

+15
-26
lines changed

1 file changed

+15
-26
lines changed

compiler/rustc_mir_transform/src/const_prop_lint.rs

+15-26
Original file line numberDiff line numberDiff line change
@@ -101,19 +101,19 @@ impl<'tcx> From<ImmTy<'tcx>> for Value<'tcx> {
101101
}
102102

103103
impl<'tcx> Value<'tcx> {
104-
fn project(
105-
&self,
106-
proj: impl Iterator<Item = Option<ProjectionElem<FieldIdx, Ty<'tcx>>>>,
107-
) -> Option<&Value<'tcx>> {
104+
fn project(&self, proj: impl Iterator<Item = Option<PlaceElem<'tcx>>>) -> Option<&Value<'tcx>> {
108105
let mut this = self;
109106
for proj in proj {
110107
this = match (proj?, this) {
111108
(ProjectionElem::Field(idx, _), Value::Aggregate { fields, .. }) => {
112109
fields.get(idx).unwrap_or(&Value::Uninit)
113110
}
114-
(ProjectionElem::Index(idx), Value::Aggregate { fields, .. }) => {
115-
fields.get(idx).unwrap_or(&Value::Uninit)
116-
}
111+
(
112+
ProjectionElem::ConstantIndex { offset, min_length: 1, from_end: false },
113+
Value::Aggregate { fields, .. },
114+
) => fields
115+
.get(FieldIdx::from_u32(offset.try_into().ok()?))
116+
.unwrap_or(&Value::Uninit),
117117
_ => return None,
118118
};
119119
}
@@ -205,7 +205,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
205205

206206
fn get_const(&self, place: Place<'tcx>) -> Option<&Value<'tcx>> {
207207
self.locals[place.local]
208-
.project(place.projection.iter().map(|proj| self.simple_projection(proj)))
208+
.project(place.projection.iter().map(|proj| self.try_eval_index_offset(proj)))
209209
}
210210

211211
/// Remove `local` from the pool of `Locals`. Allows writing to them,
@@ -719,29 +719,18 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
719719
Some(())
720720
}
721721

722-
fn simple_projection(
723-
&self,
724-
proj: ProjectionElem<Local, Ty<'tcx>>,
725-
) -> Option<ProjectionElem<FieldIdx, Ty<'tcx>>> {
722+
fn try_eval_index_offset(&self, proj: PlaceElem<'tcx>) -> Option<PlaceElem<'tcx>> {
726723
Some(match proj {
727-
ProjectionElem::Deref => ProjectionElem::Deref,
728-
ProjectionElem::Field(idx, ty) => ProjectionElem::Field(idx, ty),
729724
ProjectionElem::Index(local) => {
730725
let val = self.get_const(local.into())?;
731726
let op = val.immediate()?;
732-
ProjectionElem::Index(FieldIdx::from_u32(
733-
self.ecx.read_target_usize(op).ok()?.try_into().ok()?,
734-
))
735-
}
736-
ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
737-
ProjectionElem::ConstantIndex { offset, min_length, from_end }
738-
}
739-
ProjectionElem::Subslice { from, to, from_end } => {
740-
ProjectionElem::Subslice { from, to, from_end }
727+
ProjectionElem::ConstantIndex {
728+
offset: self.ecx.read_target_usize(op).ok()?,
729+
min_length: 1,
730+
from_end: false,
731+
}
741732
}
742-
ProjectionElem::Downcast(a, b) => ProjectionElem::Downcast(a, b),
743-
ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty),
744-
ProjectionElem::Subtype(ty) => ProjectionElem::Subtype(ty),
733+
other => other,
745734
})
746735
}
747736
}

0 commit comments

Comments
 (0)