about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2022-03-31 13:50:30 +1100
committerNicholas Nethercote <n.nethercote@gmail.com>2022-03-31 14:40:43 +1100
commitc6fedd4f1006069786a28e2054442c188408e194 (patch)
tree174686e7f1138783bfdccc7da00060f352bf1bba
parentf68a0449ed4e49705e2ee70be6e5678aa426b206 (diff)
downloadrust-c6fedd4f1006069786a28e2054442c188408e194.tar.gz
rust-c6fedd4f1006069786a28e2054442c188408e194.zip
Make `MatcherPos` not derive `Clone`.
It's only used in one place, and there we clone and then make a bunch of
modifications. It's clearer if we duplicate more explicitly, and there's
a symmetry now between `sequence()` and `empty_sequence()`.
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs32
1 files changed, 24 insertions, 8 deletions
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index 0e05440493a..618a213055e 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -132,7 +132,6 @@ struct Parent<'tt> {
 ///                            <-------------->   first submatcher; three tts, zero metavars
 ///                  <--------------------------> top-level matcher; two tts, one metavar
 /// ```
-#[derive(Clone)]
 struct MatcherPos<'tt> {
     /// The tokens that make up the current matcher. When we are within a `Sequence` or `Delimited`
     /// submatcher, this is just the contents of that submatcher.
@@ -177,6 +176,25 @@ impl<'tt> MatcherPos<'tt> {
         }
     }
 
+    fn empty_sequence(
+        parent_mp: &MatcherPos<'tt>,
+        seq: &'tt SequenceRepetition,
+        empty_matches: Lrc<NamedMatchVec>,
+    ) -> Self {
+        let mut mp = MatcherPos {
+            tts: parent_mp.tts,
+            idx: parent_mp.idx + 1,
+            matches: parent_mp.matches.clone(), // a cheap clone
+            seq_depth: parent_mp.seq_depth,
+            match_cur: parent_mp.match_cur + seq.num_captures,
+            kind: parent_mp.kind.clone(), // an expensive clone
+        };
+        for idx in parent_mp.match_cur..parent_mp.match_cur + seq.num_captures {
+            mp.push_match(idx, MatchedSeq(empty_matches.clone()));
+        }
+        mp
+    }
+
     fn sequence(
         parent_mp: Box<MatcherPos<'tt>>,
         seq: &'tt SequenceRepetition,
@@ -468,13 +486,11 @@ impl<'tt> TtParser<'tt> {
                         let op = seq.kleene.op;
                         if op == mbe::KleeneOp::ZeroOrMore || op == mbe::KleeneOp::ZeroOrOne {
                             // Allow for the possibility of zero matches of this sequence.
-                            let mut new_mp = mp.clone();
-                            new_mp.match_cur += seq.num_captures;
-                            new_mp.idx += 1;
-                            for idx in mp.match_cur..mp.match_cur + seq.num_captures {
-                                new_mp.push_match(idx, MatchedSeq(self.empty_matches.clone()));
-                            }
-                            self.cur_mps.push(new_mp);
+                            self.cur_mps.push(box MatcherPos::empty_sequence(
+                                &*mp,
+                                &seq,
+                                self.empty_matches.clone(),
+                            ));
                         }
 
                         // Allow for the possibility of one or more matches of this sequence.