about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorNicholas Nethercote <nnethercote@mozilla.com>2018-11-01 05:35:20 +1100
committerNicholas Nethercote <nnethercote@mozilla.com>2018-11-01 08:43:40 +1100
commitc60ed5d22c4c2a4885fdfdfa8c6b008d79b0fc29 (patch)
tree40c66feb00cdb17c2aba10d1b641f3230b6e9cd4 /src/libsyntax
parentd586d5d2f51489821b471f20959333558c24b129 (diff)
downloadrust-c60ed5d22c4c2a4885fdfdfa8c6b008d79b0fc29.tar.gz
rust-c60ed5d22c4c2a4885fdfdfa8c6b008d79b0fc29.zip
Share empty `Vec`s more within `MatcherPos::matches`.
`create_matches` creates a `Vec<Rc<Vec<NamedMatch>>>`. Even though all the
inner `Vec`s are empty, each one is created separately.

This commit changes `create_matches` so it instead creates one empty inner
`Vec`, and shares it.

The commit also changes `MatcherPos::matches` to a boxed slice, because its
length doesn't change.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 03a8376e763..bf91a233f7c 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -168,7 +168,7 @@ struct MatcherPos<'a> {
     /// all bound matches from the submatcher into the shared top-level `matches` vector. If `sep`
     /// and `up` are `Some`, then `matches` is _not_ the shared top-level list. Instead, if one
     /// wants the shared `matches`, one should use `up.matches`.
-    matches: Vec<Rc<Vec<NamedMatch>>>,
+    matches: Box<[Rc<Vec<NamedMatch>>]>,
     /// The position in `matches` corresponding to the first metavar in this matcher's sequence of
     /// token trees. In other words, the first metavar in the first token of `top_elts` corresponds
     /// to `matches[match_lo]`.
@@ -278,9 +278,14 @@ pub fn count_names(ms: &[TokenTree]) -> usize {
     })
 }
 
-/// Initialize `len` empty shared `Vec`s to be used to store matches of metavars.
-fn create_matches(len: usize) -> Vec<Rc<Vec<NamedMatch>>> {
-    (0..len).into_iter().map(|_| Rc::new(Vec::new())).collect()
+/// `len` `Vec`s (initially shared and empty) that will store matches of metavars.
+fn create_matches(len: usize) -> Box<[Rc<Vec<NamedMatch>>]> {
+    if len == 0 {
+        vec![]
+    } else {
+        let empty_matches = Rc::new(Vec::new());
+        vec![empty_matches.clone(); len]
+    }.into_boxed_slice()
 }
 
 /// Generate the top-level matcher position in which the "dot" is before the first token of the