1
Fork 0

Convert from using named fields to always using indices

This commit is contained in:
Niko Matsakis 2015-10-21 17:19:02 -04:00
parent 1e30f3e52b
commit 15c1da4e27
3 changed files with 27 additions and 10 deletions

View file

@ -1731,6 +1731,13 @@ impl<'tcx, 'container> VariantDefData<'tcx, 'container> {
self.fields.iter().find(|f| f.name == name) self.fields.iter().find(|f| f.name == name)
} }
#[inline]
pub fn index_of_field_named(&self,
name: ast::Name)
-> Option<usize> {
self.fields.iter().position(|f| f.name == name)
}
#[inline] #[inline]
pub fn field_named(&self, name: ast::Name) -> &FieldDefData<'tcx, 'container> { pub fn field_named(&self, name: ast::Name) -> &FieldDefData<'tcx, 'container> {
self.find_field_named(name).unwrap() self.find_field_named(name).unwrap()

View file

@ -149,16 +149,19 @@ impl<'a,'tcx> Builder<'a,'tcx> {
block.and(Rvalue::Aggregate(AggregateKind::Closure(closure_id, substs), upvars)) block.and(Rvalue::Aggregate(AggregateKind::Closure(closure_id, substs), upvars))
} }
ExprKind::Adt { adt_def, variant_index, substs, fields, base } => { // see (*) above ExprKind::Adt { adt_def, variant_index, substs, fields, base } => { // see (*) above
// first process the set of fields // first process the set of fields that were provided
// (evaluating them in order given by user)
let fields_map: FnvHashMap<_, _> = let fields_map: FnvHashMap<_, _> =
fields.into_iter() fields.into_iter()
.map(|f| (f.name, unpack!(block = this.as_operand(block, f.expr)))) .map(|f| (f.name, unpack!(block = this.as_operand(block, f.expr))))
.collect(); .collect();
let field_names = this.hir.fields(adt_def, variant_index); // if base expression is given, evaluate it now
let base = base.map(|base| unpack!(block = this.as_lvalue(block, base))); let base = base.map(|base| unpack!(block = this.as_lvalue(block, base)));
// get list of all fields that we will need
let field_names = this.hir.all_fields(adt_def, variant_index);
// for the actual values we use, take either the // for the actual values we use, take either the
// expr the user specified or, if they didn't // expr the user specified or, if they didn't
// specify something for this field name, create a // specify something for this field name, create a

View file

@ -443,10 +443,19 @@ pub type LvalueProjection<'tcx> =
pub type LvalueElem<'tcx> = pub type LvalueElem<'tcx> =
ProjectionElem<'tcx,Operand<'tcx>>; ProjectionElem<'tcx,Operand<'tcx>>;
/// Index into the list of fields found in a `VariantDef`
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum Field { pub struct Field(u32);
Named(Name),
Indexed(usize), impl Field {
pub fn new(value: usize) -> Field {
assert!(value < (u32::MAX) as usize);
Field(value as u32)
}
pub fn index(self) -> usize {
self.0 as usize
}
} }
impl<'tcx> Lvalue<'tcx> { impl<'tcx> Lvalue<'tcx> {
@ -491,10 +500,8 @@ impl<'tcx> Debug for Lvalue<'tcx> {
write!(fmt,"({:?} as {:?})", data.base, variant_index), write!(fmt,"({:?} as {:?})", data.base, variant_index),
ProjectionElem::Deref => ProjectionElem::Deref =>
write!(fmt,"(*{:?})", data.base), write!(fmt,"(*{:?})", data.base),
ProjectionElem::Field(Field::Named(name)) => ProjectionElem::Field(field) =>
write!(fmt,"{:?}.{:?}", data.base, name), write!(fmt,"{:?}.{:?}", data.base, field.index()),
ProjectionElem::Field(Field::Indexed(index)) =>
write!(fmt,"{:?}.{:?}", data.base, index),
ProjectionElem::Index(ref index) => ProjectionElem::Index(ref index) =>
write!(fmt,"{:?}[{:?}]", data.base, index), write!(fmt,"{:?}[{:?}]", data.base, index),
ProjectionElem::ConstantIndex { offset, min_length, from_end: false } => ProjectionElem::ConstantIndex { offset, min_length, from_end: false } =>