]> git.lizzy.rs Git - rust.git/commitdiff
Convert from using named fields to always using indices
authorNiko Matsakis <niko@alum.mit.edu>
Wed, 21 Oct 2015 21:19:02 +0000 (17:19 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Tue, 3 Nov 2015 09:34:59 +0000 (04:34 -0500)
src/librustc/middle/ty/mod.rs
src/librustc_mir/build/expr/as_rvalue.rs
src/librustc_mir/repr.rs

index 573634414932bb7ef708f6a40f8cb9d79959240a..aa189744701784d53abbcff6633d00869079c901 100644 (file)
@@ -1731,6 +1731,13 @@ pub fn find_field_named(&self,
         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]
     pub fn field_named(&self, name: ast::Name) -> &FieldDefData<'tcx, 'container> {
         self.find_field_named(name).unwrap()
index c5831b881abe57ce863fe637b5d95d61546dc7f8..23ca22129fdc0f99606fdba618d99e7048f8e1a1 100644 (file)
@@ -149,16 +149,19 @@ fn expr_as_rvalue(&mut self,
                 block.and(Rvalue::Aggregate(AggregateKind::Closure(closure_id, substs), upvars))
             }
             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<_, _> =
                     fields.into_iter()
                           .map(|f| (f.name, unpack!(block = this.as_operand(block, f.expr))))
                           .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)));
 
+                // 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
                 // expr the user specified or, if they didn't
                 // specify something for this field name, create a
index 54e00dc0a68ad66b917d65088cba765e18207319..5bf326ba5a5fe0b6f1787fdea9f52c75b7120767 100644 (file)
@@ -443,10 +443,19 @@ pub enum ProjectionElem<'tcx, V> {
 pub type LvalueElem<'tcx> =
     ProjectionElem<'tcx,Operand<'tcx>>;
 
+/// Index into the list of fields found in a `VariantDef`
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub enum Field {
-    Named(Name),
-    Indexed(usize),
+pub struct Field(u32);
+
+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> {
@@ -491,10 +500,8 @@ fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
                         write!(fmt,"({:?} as {:?})", data.base, variant_index),
                     ProjectionElem::Deref =>
                         write!(fmt,"(*{:?})", data.base),
-                    ProjectionElem::Field(Field::Named(name)) =>
-                        write!(fmt,"{:?}.{:?}", data.base, name),
-                    ProjectionElem::Field(Field::Indexed(index)) =>
-                        write!(fmt,"{:?}.{:?}", data.base, index),
+                    ProjectionElem::Field(field) =>
+                        write!(fmt,"{:?}.{:?}", data.base, field.index()),
                     ProjectionElem::Index(ref index) =>
                         write!(fmt,"{:?}[{:?}]", data.base, index),
                     ProjectionElem::ConstantIndex { offset, min_length, from_end: false } =>