@@ -81,22 +81,12 @@ use rustc_session::parse::ParseSess;
8181use rustc_span:: symbol:: MacroRulesNormalizedIdent ;
8282use rustc_span:: Span ;
8383
84- use smallvec:: { smallvec, SmallVec } ;
85-
8684use rustc_data_structures:: fx:: FxHashMap ;
8785use rustc_data_structures:: sync:: Lrc ;
8886use rustc_span:: symbol:: Ident ;
8987use std:: borrow:: Cow ;
9088use std:: collections:: hash_map:: Entry :: { Occupied , Vacant } ;
9189
92- // One element is enough to cover 95-99% of vectors for most benchmarks. Also, vectors longer than
93- // one frequently have many elements, not just two or three.
94- type NamedMatchVec = SmallVec < [ NamedMatch ; 1 ] > ;
95-
96- // This type is used a lot. Make sure it doesn't unintentionally get bigger.
97- #[ cfg( all( target_arch = "x86_64" , target_pointer_width = "64" ) ) ]
98- rustc_data_structures:: static_assert_size!( NamedMatchVec , 48 ) ;
99-
10090/// A unit within a matcher that a `MatcherPos` can refer to. Similar to (and derived from)
10191/// `mbe::TokenTree`, but designed specifically for fast and easy traversal during matching.
10292/// Notable differences to `mbe::TokenTree`:
@@ -221,7 +211,11 @@ struct MatcherPos {
221211 /// with one element per metavar decl in the matcher. Each element records token trees matched
222212 /// against the relevant metavar by the black box parser. An element will be a `MatchedSeq` if
223213 /// the corresponding metavar decl is within a sequence.
224- matches : Lrc < NamedMatchVec > ,
214+ ///
215+ /// It is critical to performance that this is an `Lrc`, because it gets cloned frequently when
216+ /// processing sequences. Mostly for sequence-ending possibilities that must be tried but end
217+ /// up failing.
218+ matches : Lrc < Vec < NamedMatch > > ,
225219}
226220
227221// This type is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -246,18 +240,12 @@ impl MatcherPos {
246240 let mut curr = & mut matches[ metavar_idx] ;
247241 for _ in 0 ..seq_depth - 1 {
248242 match curr {
249- MatchedSeq ( seq) => {
250- let seq = Lrc :: make_mut ( seq) ;
251- curr = seq. last_mut ( ) . unwrap ( ) ;
252- }
243+ MatchedSeq ( seq) => curr = seq. last_mut ( ) . unwrap ( ) ,
253244 _ => unreachable ! ( ) ,
254245 }
255246 }
256247 match curr {
257- MatchedSeq ( seq) => {
258- let seq = Lrc :: make_mut ( seq) ;
259- seq. push ( m) ;
260- }
248+ MatchedSeq ( seq) => seq. push ( m) ,
261249 _ => unreachable ! ( ) ,
262250 }
263251 }
@@ -350,7 +338,7 @@ pub(super) fn count_metavar_decls(matcher: &[TokenTree]) -> usize {
350338/// ```
351339#[ derive( Debug , Clone ) ]
352340crate enum NamedMatch {
353- MatchedSeq ( Lrc < NamedMatchVec > ) ,
341+ MatchedSeq ( Vec < NamedMatch > ) ,
354342
355343 // A metavar match of type `tt`.
356344 MatchedTokenTree ( rustc_ast:: tokenstream:: TokenTree ) ,
@@ -388,7 +376,7 @@ pub struct TtParser {
388376
389377 /// Pre-allocate an empty match array, so it can be cloned cheaply for macros with many rules
390378 /// that have no metavars.
391- empty_matches : Lrc < NamedMatchVec > ,
379+ empty_matches : Lrc < Vec < NamedMatch > > ,
392380}
393381
394382impl TtParser {
@@ -398,7 +386,7 @@ impl TtParser {
398386 cur_mps : vec ! [ ] ,
399387 next_mps : vec ! [ ] ,
400388 bb_mps : vec ! [ ] ,
401- empty_matches : Lrc :: new ( smallvec ! [ ] ) ,
389+ empty_matches : Lrc :: new ( vec ! [ ] ) ,
402390 }
403391 }
404392
@@ -452,11 +440,7 @@ impl TtParser {
452440 } => {
453441 // Install an empty vec for each metavar within the sequence.
454442 for metavar_idx in next_metavar..next_metavar + num_metavar_decls {
455- mp. push_match (
456- metavar_idx,
457- seq_depth,
458- MatchedSeq ( self . empty_matches . clone ( ) ) ,
459- ) ;
443+ mp. push_match ( metavar_idx, seq_depth, MatchedSeq ( vec ! [ ] ) ) ;
460444 }
461445
462446 if op == KleeneOp :: ZeroOrMore || op == KleeneOp :: ZeroOrOne {
0 commit comments