fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
place: &Place<'tcx>,
) -> CPlace<'tcx> {
- match place {
- Place::Base(base) => match base {
- PlaceBase::Local(local) => fx.get_local_place(*local),
- PlaceBase::Static(static_) => match static_.kind {
- StaticKind::Static(def_id) => {
- crate::constant::codegen_static_ref(fx, def_id, static_.ty)
- }
- StaticKind::Promoted(promoted) => {
- crate::constant::trans_promoted(fx, promoted, static_.ty)
- }
+ let base = match &place.base {
+ PlaceBase::Local(local) => fx.get_local_place(*local),
+ PlaceBase::Static(static_) => match static_.kind {
+ StaticKind::Static(def_id) => {
+ crate::constant::codegen_static_ref(fx, def_id, static_.ty)
+ }
+ StaticKind::Promoted(promoted) => {
+ crate::constant::trans_promoted(fx, promoted, static_.ty)
}
}
- Place::Projection(projection) => {
- let base = trans_place(fx, &projection.base);
- match projection.elem {
- ProjectionElem::Deref => base.place_deref(fx),
- ProjectionElem::Field(field, _ty) => base.place_field(fx, field),
- ProjectionElem::Index(local) => {
- let index = fx.get_local_place(local).to_cvalue(fx).load_scalar(fx);
- base.place_index(fx, index)
- }
- ProjectionElem::ConstantIndex {
- offset,
- min_length: _,
- from_end,
- } => {
- let index = if !from_end {
- fx.bcx.ins().iconst(fx.pointer_type, offset as i64)
- } else {
- let len = codegen_array_len(fx, base);
- fx.bcx.ins().iadd_imm(len, -(offset as i64))
- };
- base.place_index(fx, index)
+ };
+
+ trans_place_projection(fx, base, &place.projection)
+}
+
+pub fn trans_place_projection<'a, 'tcx: 'a>(
+ fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
+ base: CPlace<'tcx>,
+ projection: &Option<Box<Projection<'tcx>>>,
+) -> CPlace<'tcx> {
+ let projection = if let Some(projection) = projection {
+ projection
+ } else {
+ return base;
+ };
+
+ let base = trans_place_projection(fx, base, &projection.base);
+
+ match projection.elem {
+ ProjectionElem::Deref => base.place_deref(fx),
+ ProjectionElem::Field(field, _ty) => base.place_field(fx, field),
+ ProjectionElem::Index(local) => {
+ let index = fx.get_local_place(local).to_cvalue(fx).load_scalar(fx);
+ base.place_index(fx, index)
+ }
+ ProjectionElem::ConstantIndex {
+ offset,
+ min_length: _,
+ from_end,
+ } => {
+ let index = if !from_end {
+ fx.bcx.ins().iconst(fx.pointer_type, offset as i64)
+ } else {
+ let len = codegen_array_len(fx, base);
+ fx.bcx.ins().iadd_imm(len, -(offset as i64))
+ };
+ base.place_index(fx, index)
+ }
+ ProjectionElem::Subslice { from, to } => {
+ // These indices are generated by slice patterns.
+ // slice[from:-to] in Python terms.
+
+ match base.layout().ty.sty {
+ ty::Array(elem_ty, len) => {
+ let elem_layout = fx.layout_of(elem_ty);
+ let ptr = base.to_addr(fx);
+ let len = crate::constant::force_eval_const(fx, len).unwrap_usize(fx.tcx);
+ CPlace::for_addr(
+ fx.bcx.ins().iadd_imm(ptr, elem_layout.size.bytes() as i64 * from as i64),
+ fx.layout_of(fx.tcx.mk_array(elem_ty, len - from as u64 - to as u64)),
+ )
}
- ProjectionElem::Subslice { from, to } => {
- // These indices are generated by slice patterns.
- // slice[from:-to] in Python terms.
-
- match base.layout().ty.sty {
- ty::Array(elem_ty, len) => {
- let elem_layout = fx.layout_of(elem_ty);
- let ptr = base.to_addr(fx);
- let len = crate::constant::force_eval_const(fx, len).unwrap_usize(fx.tcx);
- CPlace::for_addr(
- fx.bcx.ins().iadd_imm(ptr, elem_layout.size.bytes() as i64 * from as i64),
- fx.layout_of(fx.tcx.mk_array(elem_ty, len - from as u64 - to as u64)),
- )
- }
- ty::Slice(elem_ty) => {
- let elem_layout = fx.layout_of(elem_ty);
- let (ptr, len) = base.to_addr_maybe_unsized(fx);
- let len = len.unwrap();
- CPlace::for_addr_with_extra(
- fx.bcx.ins().iadd_imm(ptr, elem_layout.size.bytes() as i64 * from as i64),
- fx.bcx.ins().iadd_imm(len, -(from as i64 + to as i64)),
- base.layout(),
- )
- }
- _ => unreachable!(),
- }
+ ty::Slice(elem_ty) => {
+ let elem_layout = fx.layout_of(elem_ty);
+ let (ptr, len) = base.to_addr_maybe_unsized(fx);
+ let len = len.unwrap();
+ CPlace::for_addr_with_extra(
+ fx.bcx.ins().iadd_imm(ptr, elem_layout.size.bytes() as i64 * from as i64),
+ fx.bcx.ins().iadd_imm(len, -(from as i64 + to as i64)),
+ base.layout(),
+ )
}
- ProjectionElem::Downcast(_adt_def, variant) => base.downcast_variant(fx, variant),
+ _ => unreachable!(),
}
}
+ ProjectionElem::Downcast(_adt_def, variant) => base.downcast_variant(fx, variant),
}
}