@@ -107,12 +107,12 @@ use std::rc::Rc;
107107/// Either a sequence of token trees or a single one. This is used as the representation of the
108108/// sequence of tokens that make up a matcher.
109109#[ derive( Clone ) ]
110- enum TokenTreeOrTokenTreeSlice < ' a > {
110+ enum TokenTreeOrTokenTreeSlice < ' tt > {
111111 Tt ( TokenTree ) ,
112- TtSeq ( & ' a [ TokenTree ] ) ,
112+ TtSeq ( & ' tt [ TokenTree ] ) ,
113113}
114114
115- impl < ' a > TokenTreeOrTokenTreeSlice < ' a > {
115+ impl < ' tt > TokenTreeOrTokenTreeSlice < ' tt > {
116116 /// Returns the number of constituent top-level token trees of `self` (top-level in that it
117117 /// will not recursively descend into subtrees).
118118 fn len ( & self ) -> usize {
@@ -136,23 +136,41 @@ impl<'a> TokenTreeOrTokenTreeSlice<'a> {
136136/// This is used by `inner_parse_loop` to keep track of delimited submatchers that we have
137137/// descended into.
138138#[ derive( Clone ) ]
139- struct MatcherTtFrame < ' a > {
139+ struct MatcherTtFrame < ' tt > {
140140 /// The "parent" matcher that we are descending into.
141- elts : TokenTreeOrTokenTreeSlice < ' a > ,
141+ elts : TokenTreeOrTokenTreeSlice < ' tt > ,
142142 /// The position of the "dot" in `elts` at the time we descended.
143143 idx : usize ,
144144}
145145
146146type NamedMatchVec = SmallVec < [ NamedMatch ; 4 ] > ;
147147
148- /// Represents a single "position" (aka "matcher position", aka "item"), as described in the module
149- /// documentation.
148+ /// Represents a single "position" (aka "matcher position", aka "item"), as
149+ /// described in the module documentation.
150+ ///
151+ /// Here:
152+ ///
153+ /// - `'root` represents the lifetime of the stack slot that holds the root
154+ /// `MatcherPos`. As described in `MatcherPosHandle`, the root `MatcherPos`
155+ /// structure is stored on the stack, but subsequent instances are put into
156+ /// the heap.
157+ /// - `'tt` represents the lifetime of the token trees that this matcher
158+ /// position refers to.
159+ ///
160+ /// It is important to distinguish these two lifetimes because we have a
161+ /// `SmallVec<TokenTreeOrTokenTreeSlice<'tt>>` below, and the destructor of
162+ /// that is considered to possibly access the data from its elements (it lacks
163+ /// a `#[may_dangle]` attribute). As a result, the compiler needs to know that
164+ /// all the elements in that `SmallVec` strictly outlive the root stack slot
165+ /// lifetime. By separating `'tt` from `'root`, we can show that.
150166#[ derive( Clone ) ]
151- struct MatcherPos < ' a > {
167+ struct MatcherPos < ' root , ' tt : ' root > {
152168 /// The token or sequence of tokens that make up the matcher
153- top_elts : TokenTreeOrTokenTreeSlice < ' a > ,
169+ top_elts : TokenTreeOrTokenTreeSlice < ' tt > ,
170+
154171 /// The position of the "dot" in this matcher
155172 idx : usize ,
173+
156174 /// The first span of source source that the beginning of this matcher corresponds to. In other
157175 /// words, the token in the source whose span is `sp_open` is matched against the first token of
158176 /// the matcher.
@@ -182,26 +200,31 @@ struct MatcherPos<'a> {
182200 /// in this matcher.
183201 match_hi : usize ,
184202
185- // Specifically used if we are matching a repetition. If we aren't both should be `None`.
203+ // The following fields are used if we are matching a repetition. If we aren't, they should be
204+ // `None`.
205+
186206 /// The KleeneOp of this sequence if we are in a repetition.
187207 seq_op : Option < quoted:: KleeneOp > ,
188- /// The separator if we are in a repetition
208+
209+ /// The separator if we are in a repetition.
189210 sep : Option < Token > ,
211+
190212 /// The "parent" matcher position if we are in a repetition. That is, the matcher position just
191213 /// before we enter the sequence.
192- up : Option < MatcherPosHandle < ' a > > ,
214+ up : Option < MatcherPosHandle < ' root , ' tt > > ,
193215
194- // Specifically used to "unzip" token trees. By "unzip", we mean to unwrap the delimiters from
195- // a delimited token tree (e.g. something wrapped in `(` `)`) or to get the contents of a doc
196- // comment...
216+ /// Specifically used to "unzip" token trees. By "unzip", we mean to unwrap the delimiters from
217+ /// a delimited token tree (e.g. something wrapped in `(` `)`) or to get the contents of a doc
218+ /// comment...
219+ ///
197220 /// When matching against matchers with nested delimited submatchers (e.g. `pat ( pat ( .. )
198221 /// pat ) pat`), we need to keep track of the matchers we are descending into. This stack does
199222 /// that where the bottom of the stack is the outermost matcher.
200- // Also, throughout the comments, this "descent" is often referred to as "unzipping"...
201- stack : Vec < MatcherTtFrame < ' a > > ,
223+ /// Also, throughout the comments, this "descent" is often referred to as "unzipping"...
224+ stack : SmallVec < [ MatcherTtFrame < ' tt > ; 1 ] > ,
202225}
203226
204- impl < ' a > MatcherPos < ' a > {
227+ impl < ' root , ' tt > MatcherPos < ' root , ' tt > {
205228 /// Add `m` as a named match for the `idx`-th metavar.
206229 fn push_match ( & mut self , idx : usize , m : NamedMatch ) {
207230 let matches = Rc :: make_mut ( & mut self . matches [ idx] ) ;
@@ -218,12 +241,12 @@ impl<'a> MatcherPos<'a> {
218241// Therefore, the initial MatcherPos is always allocated on the stack,
219242// subsequent ones (of which there aren't that many) are allocated on the heap,
220243// and this type is used to encapsulate both cases.
221- enum MatcherPosHandle < ' a > {
222- Ref ( & ' a mut MatcherPos < ' a > ) ,
223- Box ( Box < MatcherPos < ' a > > ) ,
244+ enum MatcherPosHandle < ' root , ' tt : ' root > {
245+ Ref ( & ' root mut MatcherPos < ' root , ' tt > ) ,
246+ Box ( Box < MatcherPos < ' root , ' tt > > ) ,
224247}
225248
226- impl < ' a > Clone for MatcherPosHandle < ' a > {
249+ impl < ' root , ' tt > Clone for MatcherPosHandle < ' root , ' tt > {
227250 // This always produces a new Box.
228251 fn clone ( & self ) -> Self {
229252 MatcherPosHandle :: Box ( match * self {
@@ -233,8 +256,8 @@ impl<'a> Clone for MatcherPosHandle<'a> {
233256 }
234257}
235258
236- impl < ' a > Deref for MatcherPosHandle < ' a > {
237- type Target = MatcherPos < ' a > ;
259+ impl < ' root , ' tt > Deref for MatcherPosHandle < ' root , ' tt > {
260+ type Target = MatcherPos < ' root , ' tt > ;
238261 fn deref ( & self ) -> & Self :: Target {
239262 match * self {
240263 MatcherPosHandle :: Ref ( ref r) => r,
@@ -243,8 +266,8 @@ impl<'a> Deref for MatcherPosHandle<'a> {
243266 }
244267}
245268
246- impl < ' a > DerefMut for MatcherPosHandle < ' a > {
247- fn deref_mut ( & mut self ) -> & mut MatcherPos < ' a > {
269+ impl < ' root , ' tt > DerefMut for MatcherPosHandle < ' root , ' tt > {
270+ fn deref_mut ( & mut self ) -> & mut MatcherPos < ' root , ' tt > {
248271 match * self {
249272 MatcherPosHandle :: Ref ( ref mut r) => r,
250273 MatcherPosHandle :: Box ( ref mut b) => b,
@@ -292,7 +315,7 @@ fn create_matches(len: usize) -> Box<[Rc<NamedMatchVec>]> {
292315
293316/// Generate the top-level matcher position in which the "dot" is before the first token of the
294317/// matcher `ms` and we are going to start matching at the span `open` in the source.
295- fn initial_matcher_pos ( ms : & [ TokenTree ] , open : Span ) -> MatcherPos {
318+ fn initial_matcher_pos < ' root , ' tt > ( ms : & ' tt [ TokenTree ] , open : Span ) -> MatcherPos < ' root , ' tt > {
296319 let match_idx_hi = count_names ( ms) ;
297320 let matches = create_matches ( match_idx_hi) ;
298321 MatcherPos {
@@ -312,7 +335,7 @@ fn initial_matcher_pos(ms: &[TokenTree], open: Span) -> MatcherPos {
312335 match_hi : match_idx_hi,
313336
314337 // Haven't descended into any delimiters, so empty stack
315- stack : vec ! [ ] ,
338+ stack : smallvec ! [ ] ,
316339
317340 // Haven't descended into any sequences, so both of these are `None`.
318341 seq_op : None ,
@@ -445,12 +468,12 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
445468/// # Returns
446469///
447470/// A `ParseResult`. Note that matches are kept track of through the items generated.
448- fn inner_parse_loop < ' a > (
471+ fn inner_parse_loop < ' root , ' tt > (
449472 sess : & ParseSess ,
450- cur_items : & mut SmallVec < [ MatcherPosHandle < ' a > ; 1 ] > ,
451- next_items : & mut Vec < MatcherPosHandle < ' a > > ,
452- eof_items : & mut SmallVec < [ MatcherPosHandle < ' a > ; 1 ] > ,
453- bb_items : & mut SmallVec < [ MatcherPosHandle < ' a > ; 1 ] > ,
473+ cur_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
474+ next_items : & mut Vec < MatcherPosHandle < ' root , ' tt > > ,
475+ eof_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
476+ bb_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
454477 token : & Token ,
455478 span : syntax_pos:: Span ,
456479) -> ParseResult < ( ) > {
@@ -554,7 +577,7 @@ fn inner_parse_loop<'a>(
554577
555578 let matches = create_matches ( item. matches . len ( ) ) ;
556579 cur_items. push ( MatcherPosHandle :: Box ( Box :: new ( MatcherPos {
557- stack : vec ! [ ] ,
580+ stack : smallvec ! [ ] ,
558581 sep : seq. separator . clone ( ) ,
559582 seq_op : Some ( seq. op ) ,
560583 idx : 0 ,
0 commit comments