Rollup merge of #91278 - SparrowLii:place, r=spastorino
Use iterator instead of recursion in `codegen_place` This PR fixes the FIXME in `codegen_place` about using iterator instead of recursion when processing the `projection` field in `mir::PlaceRef`. At the same time, it also reduces the right drift.
This commit is contained in:
commit
3a1db90efb
1 changed files with 68 additions and 77 deletions
|
@ -429,30 +429,31 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
let cx = self.cx;
|
let cx = self.cx;
|
||||||
let tcx = self.cx.tcx();
|
let tcx = self.cx.tcx();
|
||||||
|
|
||||||
let result = match place_ref {
|
let mut base = 0;
|
||||||
mir::PlaceRef { local, projection: [] } => match self.locals[local] {
|
let mut cg_base = match self.locals[place_ref.local] {
|
||||||
LocalRef::Place(place) => {
|
LocalRef::Place(place) => place,
|
||||||
return place;
|
LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
|
||||||
}
|
|
||||||
LocalRef::UnsizedPlace(place) => {
|
|
||||||
return bx.load_operand(place).deref(cx);
|
|
||||||
}
|
|
||||||
LocalRef::Operand(..) => {
|
LocalRef::Operand(..) => {
|
||||||
|
if let Some(elem) = place_ref
|
||||||
|
.projection
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.find(|elem| matches!(elem.1, mir::ProjectionElem::Deref))
|
||||||
|
{
|
||||||
|
base = elem.0 + 1;
|
||||||
|
self.codegen_consume(
|
||||||
|
bx,
|
||||||
|
mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref },
|
||||||
|
)
|
||||||
|
.deref(bx.cx())
|
||||||
|
} else {
|
||||||
bug!("using operand local {:?} as place", place_ref);
|
bug!("using operand local {:?} as place", place_ref);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
mir::PlaceRef { local, projection: [proj_base @ .., mir::ProjectionElem::Deref] } => {
|
|
||||||
// Load the pointer from its location.
|
|
||||||
self.codegen_consume(bx, mir::PlaceRef { local, projection: proj_base })
|
|
||||||
.deref(bx.cx())
|
|
||||||
}
|
}
|
||||||
mir::PlaceRef { local, projection: &[ref proj_base @ .., elem] } => {
|
};
|
||||||
// FIXME turn this recursion into iteration
|
for elem in place_ref.projection[base..].iter() {
|
||||||
let cg_base =
|
cg_base = match elem.clone() {
|
||||||
self.codegen_place(bx, mir::PlaceRef { local, projection: proj_base });
|
mir::ProjectionElem::Deref => bx.load_operand(cg_base).deref(bx.cx()),
|
||||||
|
|
||||||
match elem {
|
|
||||||
mir::ProjectionElem::Deref => bug!(),
|
|
||||||
mir::ProjectionElem::Field(ref field, _) => {
|
mir::ProjectionElem::Field(ref field, _) => {
|
||||||
cg_base.project_field(bx, field.index())
|
cg_base.project_field(bx, field.index())
|
||||||
}
|
}
|
||||||
|
@ -462,29 +463,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
let llindex = index.immediate();
|
let llindex = index.immediate();
|
||||||
cg_base.project_index(bx, llindex)
|
cg_base.project_index(bx, llindex)
|
||||||
}
|
}
|
||||||
mir::ProjectionElem::ConstantIndex {
|
mir::ProjectionElem::ConstantIndex { offset, from_end: false, min_length: _ } => {
|
||||||
offset,
|
|
||||||
from_end: false,
|
|
||||||
min_length: _,
|
|
||||||
} => {
|
|
||||||
let lloffset = bx.cx().const_usize(offset as u64);
|
let lloffset = bx.cx().const_usize(offset as u64);
|
||||||
cg_base.project_index(bx, lloffset)
|
cg_base.project_index(bx, lloffset)
|
||||||
}
|
}
|
||||||
mir::ProjectionElem::ConstantIndex {
|
mir::ProjectionElem::ConstantIndex { offset, from_end: true, min_length: _ } => {
|
||||||
offset,
|
|
||||||
from_end: true,
|
|
||||||
min_length: _,
|
|
||||||
} => {
|
|
||||||
let lloffset = bx.cx().const_usize(offset as u64);
|
let lloffset = bx.cx().const_usize(offset as u64);
|
||||||
let lllen = cg_base.len(bx.cx());
|
let lllen = cg_base.len(bx.cx());
|
||||||
let llindex = bx.sub(lllen, lloffset);
|
let llindex = bx.sub(lllen, lloffset);
|
||||||
cg_base.project_index(bx, llindex)
|
cg_base.project_index(bx, llindex)
|
||||||
}
|
}
|
||||||
mir::ProjectionElem::Subslice { from, to, from_end } => {
|
mir::ProjectionElem::Subslice { from, to, from_end } => {
|
||||||
let mut subslice =
|
let mut subslice = cg_base.project_index(bx, bx.cx().const_usize(from as u64));
|
||||||
cg_base.project_index(bx, bx.cx().const_usize(from as u64));
|
|
||||||
let projected_ty =
|
let projected_ty =
|
||||||
PlaceTy::from_ty(cg_base.layout.ty).projection_ty(tcx, elem).ty;
|
PlaceTy::from_ty(cg_base.layout.ty).projection_ty(tcx, elem.clone()).ty;
|
||||||
subslice.layout = bx.cx().layout_of(self.monomorphize(projected_ty));
|
subslice.layout = bx.cx().layout_of(self.monomorphize(projected_ty));
|
||||||
|
|
||||||
if subslice.layout.is_unsized() {
|
if subslice.layout.is_unsized() {
|
||||||
|
@ -505,11 +497,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
subslice
|
subslice
|
||||||
}
|
}
|
||||||
mir::ProjectionElem::Downcast(_, v) => cg_base.project_downcast(bx, v),
|
mir::ProjectionElem::Downcast(_, v) => cg_base.project_downcast(bx, v),
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
debug!("codegen_place(place={:?}) => {:?}", place_ref, result);
|
}
|
||||||
result
|
debug!("codegen_place(place={:?}) => {:?}", place_ref, cg_base);
|
||||||
|
cg_base
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn monomorphized_place_ty(&self, place_ref: mir::PlaceRef<'tcx>) -> Ty<'tcx> {
|
pub fn monomorphized_place_ty(&self, place_ref: mir::PlaceRef<'tcx>) -> Ty<'tcx> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue