about summary refs log tree commit diff
path: root/src/libsyntax/util
diff options
context:
space:
mode:
authorChristopher Chambers <chris.chambers@peanutcode.com>2015-04-10 21:50:23 -0500
committerChristopher Chambers <chris.chambers@peanutcode.com>2015-04-10 21:50:23 -0500
commitb16cfacbccee272ed8a30aec1f5c25e9f845d1a8 (patch)
tree47cefbeacca81d789e8462d3ce82f787fbd13edb /src/libsyntax/util
parent19343860aa44d1c31a7802df22349f055ed9da16 (diff)
downloadrust-b16cfacbccee272ed8a30aec1f5c25e9f845d1a8.tar.gz
rust-b16cfacbccee272ed8a30aec1f5c25e9f845d1a8.zip
Improves semicolon expansion efficiency, corrects bt_pop placement.
Implements pop() on SmallVector, and uses it to expand the final semicolon
in a statement macro expansion more efficiently.

Corrects the placement of the call to fld.cx.bt_pop().  It must run
unconditionally to reverse the corresponding push.
Diffstat (limited to 'src/libsyntax/util')
-rw-r--r--src/libsyntax/util/small_vector.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs
index 1649934f4b1..c4b096d656f 100644
--- a/src/libsyntax/util/small_vector.rs
+++ b/src/libsyntax/util/small_vector.rs
@@ -69,6 +69,42 @@ impl<T> SmallVector<T> {
         }
     }
 
+    pub fn pop(&mut self) -> Option<T> {
+        match self.repr {
+            Zero => None,
+            One(..) => {
+                let one = mem::replace(&mut self.repr, Zero);
+                match one {
+                    One(v1) => Some(v1),
+                    _ => unreachable!()
+                }
+            }
+            Many(..) => {
+                let mut many = mem::replace(&mut self.repr, Zero);
+                let item =
+                    match many {
+                        Many(ref mut vs) if vs.len() == 1 => {
+                            // self.repr is already Zero
+                            vs.pop()
+                        },
+                        Many(ref mut vs) if vs.len() == 2 => {
+                            let item = vs.pop();
+                            mem::replace(&mut self.repr, One(vs.pop().unwrap()));
+                            item
+                        },
+                        Many(ref mut vs) if vs.len() > 2 => {
+                            let item = vs.pop();
+                            let rest = mem::replace(vs, vec!());
+                            mem::replace(&mut self.repr, Many(rest));
+                            item
+                        },
+                        _ => unreachable!()
+                    };
+                item
+            }
+        }
+    }
+
     pub fn push(&mut self, v: T) {
         match self.repr {
             Zero => self.repr = One(v),