xref: /linux/rust/syn/punctuated.rs (revision 808c999fc9e7c366fd47da564e69d579c1dc8279)
1 //! A punctuated sequence of syntax tree nodes separated by punctuation.
2 //!
3 //! Lots of things in Rust are punctuated sequences.
4 //!
5 //! - The fields of a struct are `Punctuated<Field, Token![,]>`.
6 //! - The segments of a path are `Punctuated<PathSegment, Token![::]>`.
7 //! - The bounds on a generic parameter are `Punctuated<TypeParamBound,
8 //!   Token![+]>`.
9 //! - The arguments to a function call are `Punctuated<Expr, Token![,]>`.
10 //!
11 //! This module provides a common representation for these punctuated sequences
12 //! in the form of the [`Punctuated<T, P>`] type. We store a vector of pairs of
13 //! syntax tree node + punctuation, where every node in the sequence is followed
14 //! by punctuation except for possibly the final one.
15 //!
16 //! [`Punctuated<T, P>`]: Punctuated
17 //!
18 //! ```text
19 //! a_function_call(arg1, arg2, arg3);
20 //!                 ~~~~^ ~~~~^ ~~~~
21 //! ```
22 
23 use crate::drops::{NoDrop, TrivialDrop};
24 #[cfg(feature = "parsing")]
25 use crate::error::Result;
26 #[cfg(feature = "parsing")]
27 use crate::parse::{Parse, ParseStream};
28 #[cfg(feature = "parsing")]
29 use crate::token::Token;
30 #[cfg(feature = "extra-traits")]
31 use std::fmt::{self, Debug};
32 #[cfg(feature = "extra-traits")]
33 use std::hash::{Hash, Hasher};
34 #[cfg(any(feature = "full", feature = "derive"))]
35 use std::iter;
36 use std::ops::{Index, IndexMut};
37 use std::option;
38 use std::slice;
39 use std::vec;
40 
41 /// **A punctuated sequence of syntax tree nodes of type `T` separated by
42 /// punctuation of type `P`.**
43 ///
44 /// Refer to the [module documentation] for details about punctuated sequences.
45 ///
46 /// [module documentation]: self
47 pub struct Punctuated<T, P> {
48     inner: Vec<(T, P)>,
49     last: Option<Box<T>>,
50 }
51 
52 impl<T, P> Punctuated<T, P> {
53     /// Creates an empty punctuated sequence.
54     pub const fn new() -> Self {
55         Punctuated {
56             inner: Vec::new(),
57             last: None,
58         }
59     }
60 
61     /// Determines whether this punctuated sequence is empty, meaning it
62     /// contains no syntax tree nodes or punctuation.
63     pub fn is_empty(&self) -> bool {
64         self.inner.len() == 0 && self.last.is_none()
65     }
66 
67     /// Returns the number of syntax tree nodes in this punctuated sequence.
68     ///
69     /// This is the number of nodes of type `T`, not counting the punctuation of
70     /// type `P`.
71     pub fn len(&self) -> usize {
72         self.inner.len() + if self.last.is_some() { 1 } else { 0 }
73     }
74 
75     /// Borrows the first element in this sequence.
76     pub fn first(&self) -> Option<&T> {
77         self.iter().next()
78     }
79 
80     /// Mutably borrows the first element in this sequence.
81     pub fn first_mut(&mut self) -> Option<&mut T> {
82         self.iter_mut().next()
83     }
84 
85     /// Borrows the last element in this sequence.
86     pub fn last(&self) -> Option<&T> {
87         self.iter().next_back()
88     }
89 
90     /// Mutably borrows the last element in this sequence.
91     pub fn last_mut(&mut self) -> Option<&mut T> {
92         self.iter_mut().next_back()
93     }
94 
95     /// Borrows the element at the given index.
96     pub fn get(&self, index: usize) -> Option<&T> {
97         if let Some((value, _punct)) = self.inner.get(index) {
98             Some(value)
99         } else if index == self.inner.len() {
100             self.last.as_deref()
101         } else {
102             None
103         }
104     }
105 
106     /// Mutably borrows the element at the given index.
107     pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
108         let inner_len = self.inner.len();
109         if let Some((value, _punct)) = self.inner.get_mut(index) {
110             Some(value)
111         } else if index == inner_len {
112             self.last.as_deref_mut()
113         } else {
114             None
115         }
116     }
117 
118     /// Returns an iterator over borrowed syntax tree nodes of type `&T`.
119     pub fn iter(&self) -> Iter<T> {
120         Iter {
121             inner: Box::new(NoDrop::new(PrivateIter {
122                 inner: self.inner.iter(),
123                 last: self.last.as_ref().map(Box::as_ref).into_iter(),
124             })),
125         }
126     }
127 
128     /// Returns an iterator over mutably borrowed syntax tree nodes of type
129     /// `&mut T`.
130     pub fn iter_mut(&mut self) -> IterMut<T> {
131         IterMut {
132             inner: Box::new(NoDrop::new(PrivateIterMut {
133                 inner: self.inner.iter_mut(),
134                 last: self.last.as_mut().map(Box::as_mut).into_iter(),
135             })),
136         }
137     }
138 
139     /// Returns an iterator over the contents of this sequence as borrowed
140     /// punctuated pairs.
141     pub fn pairs(&self) -> Pairs<T, P> {
142         Pairs {
143             inner: self.inner.iter(),
144             last: self.last.as_ref().map(Box::as_ref).into_iter(),
145         }
146     }
147 
148     /// Returns an iterator over the contents of this sequence as mutably
149     /// borrowed punctuated pairs.
150     pub fn pairs_mut(&mut self) -> PairsMut<T, P> {
151         PairsMut {
152             inner: self.inner.iter_mut(),
153             last: self.last.as_mut().map(Box::as_mut).into_iter(),
154         }
155     }
156 
157     /// Returns an iterator over the contents of this sequence as owned
158     /// punctuated pairs.
159     pub fn into_pairs(self) -> IntoPairs<T, P> {
160         IntoPairs {
161             inner: self.inner.into_iter(),
162             last: self.last.map(|t| *t).into_iter(),
163         }
164     }
165 
166     /// Appends a syntax tree node onto the end of this punctuated sequence. The
167     /// sequence must already have a trailing punctuation, or be empty.
168     ///
169     /// Use [`push`] instead if the punctuated sequence may or may not already
170     /// have trailing punctuation.
171     ///
172     /// [`push`]: Punctuated::push
173     ///
174     /// # Panics
175     ///
176     /// Panics if the sequence is nonempty and does not already have a trailing
177     /// punctuation.
178     pub fn push_value(&mut self, value: T) {
179         assert!(
180             self.empty_or_trailing(),
181             "Punctuated::push_value: cannot push value if Punctuated is missing trailing punctuation",
182         );
183 
184         self.last = Some(Box::new(value));
185     }
186 
187     /// Appends a trailing punctuation onto the end of this punctuated sequence.
188     /// The sequence must be non-empty and must not already have trailing
189     /// punctuation.
190     ///
191     /// # Panics
192     ///
193     /// Panics if the sequence is empty or already has a trailing punctuation.
194     pub fn push_punct(&mut self, punctuation: P) {
195         assert!(
196             self.last.is_some(),
197             "Punctuated::push_punct: cannot push punctuation if Punctuated is empty or already has trailing punctuation",
198         );
199 
200         let last = self.last.take().unwrap();
201         self.inner.push((*last, punctuation));
202     }
203 
204     /// Removes the last punctuated pair from this sequence, or `None` if the
205     /// sequence is empty.
206     pub fn pop(&mut self) -> Option<Pair<T, P>> {
207         if self.last.is_some() {
208             self.last.take().map(|t| Pair::End(*t))
209         } else {
210             self.inner.pop().map(|(t, p)| Pair::Punctuated(t, p))
211         }
212     }
213 
214     /// Removes the trailing punctuation from this punctuated sequence, or
215     /// `None` if there isn't any.
216     pub fn pop_punct(&mut self) -> Option<P> {
217         if self.last.is_some() {
218             None
219         } else {
220             let (t, p) = self.inner.pop()?;
221             self.last = Some(Box::new(t));
222             Some(p)
223         }
224     }
225 
226     /// Determines whether this punctuated sequence ends with a trailing
227     /// punctuation.
228     pub fn trailing_punct(&self) -> bool {
229         self.last.is_none() && !self.is_empty()
230     }
231 
232     /// Returns true if either this `Punctuated` is empty, or it has a trailing
233     /// punctuation.
234     ///
235     /// Equivalent to `punctuated.is_empty() || punctuated.trailing_punct()`.
236     pub fn empty_or_trailing(&self) -> bool {
237         self.last.is_none()
238     }
239 
240     /// Appends a syntax tree node onto the end of this punctuated sequence.
241     ///
242     /// If there is not a trailing punctuation in this sequence when this method
243     /// is called, the default value of punctuation type `P` is inserted before
244     /// the given value of type `T`.
245     pub fn push(&mut self, value: T)
246     where
247         P: Default,
248     {
249         if !self.empty_or_trailing() {
250             self.push_punct(Default::default());
251         }
252         self.push_value(value);
253     }
254 
255     /// Inserts an element at position `index`.
256     ///
257     /// # Panics
258     ///
259     /// Panics if `index` is greater than the number of elements previously in
260     /// this punctuated sequence.
261     pub fn insert(&mut self, index: usize, value: T)
262     where
263         P: Default,
264     {
265         assert!(
266             index <= self.len(),
267             "Punctuated::insert: index out of range",
268         );
269 
270         if index == self.len() {
271             self.push(value);
272         } else {
273             self.inner.insert(index, (value, Default::default()));
274         }
275     }
276 
277     /// Clears the sequence of all values and punctuation, making it empty.
278     pub fn clear(&mut self) {
279         self.inner.clear();
280         self.last = None;
281     }
282 
283     /// Parses zero or more occurrences of `T` separated by punctuation of type
284     /// `P`, with optional trailing punctuation.
285     ///
286     /// Parsing continues until the end of this parse stream. The entire content
287     /// of this parse stream must consist of `T` and `P`.
288     #[cfg(feature = "parsing")]
289     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
290     pub fn parse_terminated(input: ParseStream) -> Result<Self>
291     where
292         T: Parse,
293         P: Parse,
294     {
295         Self::parse_terminated_with(input, T::parse)
296     }
297 
298     /// Parses zero or more occurrences of `T` using the given parse function,
299     /// separated by punctuation of type `P`, with optional trailing
300     /// punctuation.
301     ///
302     /// Like [`parse_terminated`], the entire content of this stream is expected
303     /// to be parsed.
304     ///
305     /// [`parse_terminated`]: Punctuated::parse_terminated
306     #[cfg(feature = "parsing")]
307     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
308     pub fn parse_terminated_with<'a>(
309         input: ParseStream<'a>,
310         parser: fn(ParseStream<'a>) -> Result<T>,
311     ) -> Result<Self>
312     where
313         P: Parse,
314     {
315         let mut punctuated = Punctuated::new();
316 
317         loop {
318             if input.is_empty() {
319                 break;
320             }
321             let value = parser(input)?;
322             punctuated.push_value(value);
323             if input.is_empty() {
324                 break;
325             }
326             let punct = input.parse()?;
327             punctuated.push_punct(punct);
328         }
329 
330         Ok(punctuated)
331     }
332 
333     /// Parses one or more occurrences of `T` separated by punctuation of type
334     /// `P`, not accepting trailing punctuation.
335     ///
336     /// Parsing continues as long as punctuation `P` is present at the head of
337     /// the stream. This method returns upon parsing a `T` and observing that it
338     /// is not followed by a `P`, even if there are remaining tokens in the
339     /// stream.
340     #[cfg(feature = "parsing")]
341     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
342     pub fn parse_separated_nonempty(input: ParseStream) -> Result<Self>
343     where
344         T: Parse,
345         P: Token + Parse,
346     {
347         Self::parse_separated_nonempty_with(input, T::parse)
348     }
349 
350     /// Parses one or more occurrences of `T` using the given parse function,
351     /// separated by punctuation of type `P`, not accepting trailing
352     /// punctuation.
353     ///
354     /// Like [`parse_separated_nonempty`], may complete early without parsing
355     /// the entire content of this stream.
356     ///
357     /// [`parse_separated_nonempty`]: Punctuated::parse_separated_nonempty
358     #[cfg(feature = "parsing")]
359     #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
360     pub fn parse_separated_nonempty_with<'a>(
361         input: ParseStream<'a>,
362         parser: fn(ParseStream<'a>) -> Result<T>,
363     ) -> Result<Self>
364     where
365         P: Token + Parse,
366     {
367         let mut punctuated = Punctuated::new();
368 
369         loop {
370             let value = parser(input)?;
371             punctuated.push_value(value);
372             if !P::peek(input.cursor()) {
373                 break;
374             }
375             let punct = input.parse()?;
376             punctuated.push_punct(punct);
377         }
378 
379         Ok(punctuated)
380     }
381 }
382 
383 #[cfg(feature = "clone-impls")]
384 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
385 impl<T, P> Clone for Punctuated<T, P>
386 where
387     T: Clone,
388     P: Clone,
389 {
390     fn clone(&self) -> Self {
391         Punctuated {
392             inner: self.inner.clone(),
393             last: self.last.clone(),
394         }
395     }
396 
397     fn clone_from(&mut self, other: &Self) {
398         self.inner.clone_from(&other.inner);
399         self.last.clone_from(&other.last);
400     }
401 }
402 
403 #[cfg(feature = "extra-traits")]
404 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
405 impl<T, P> Eq for Punctuated<T, P>
406 where
407     T: Eq,
408     P: Eq,
409 {
410 }
411 
412 #[cfg(feature = "extra-traits")]
413 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
414 impl<T, P> PartialEq for Punctuated<T, P>
415 where
416     T: PartialEq,
417     P: PartialEq,
418 {
419     fn eq(&self, other: &Self) -> bool {
420         let Punctuated { inner, last } = self;
421         *inner == other.inner && *last == other.last
422     }
423 }
424 
425 #[cfg(feature = "extra-traits")]
426 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
427 impl<T, P> Hash for Punctuated<T, P>
428 where
429     T: Hash,
430     P: Hash,
431 {
432     fn hash<H: Hasher>(&self, state: &mut H) {
433         let Punctuated { inner, last } = self;
434         inner.hash(state);
435         last.hash(state);
436     }
437 }
438 
439 #[cfg(feature = "extra-traits")]
440 #[cfg_attr(docsrs, doc(cfg(feature = "extra-traits")))]
441 impl<T: Debug, P: Debug> Debug for Punctuated<T, P> {
442     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
443         let mut list = f.debug_list();
444         for (t, p) in &self.inner {
445             list.entry(t);
446             list.entry(p);
447         }
448         if let Some(last) = &self.last {
449             list.entry(last);
450         }
451         list.finish()
452     }
453 }
454 
455 impl<T, P> FromIterator<T> for Punctuated<T, P>
456 where
457     P: Default,
458 {
459     fn from_iter<I: IntoIterator<Item = T>>(i: I) -> Self {
460         let mut ret = Punctuated::new();
461         ret.extend(i);
462         ret
463     }
464 }
465 
466 impl<T, P> Extend<T> for Punctuated<T, P>
467 where
468     P: Default,
469 {
470     fn extend<I: IntoIterator<Item = T>>(&mut self, i: I) {
471         for value in i {
472             self.push(value);
473         }
474     }
475 }
476 
477 impl<T, P> FromIterator<Pair<T, P>> for Punctuated<T, P> {
478     fn from_iter<I: IntoIterator<Item = Pair<T, P>>>(i: I) -> Self {
479         let mut ret = Punctuated::new();
480         do_extend(&mut ret, i.into_iter());
481         ret
482     }
483 }
484 
485 impl<T, P> Extend<Pair<T, P>> for Punctuated<T, P>
486 where
487     P: Default,
488 {
489     fn extend<I: IntoIterator<Item = Pair<T, P>>>(&mut self, i: I) {
490         if !self.empty_or_trailing() {
491             self.push_punct(P::default());
492         }
493         do_extend(self, i.into_iter());
494     }
495 }
496 
497 fn do_extend<T, P, I>(punctuated: &mut Punctuated<T, P>, i: I)
498 where
499     I: Iterator<Item = Pair<T, P>>,
500 {
501     let mut nomore = false;
502     for pair in i {
503         if nomore {
504             panic!("punctuated extended with items after a Pair::End");
505         }
506         match pair {
507             Pair::Punctuated(a, b) => punctuated.inner.push((a, b)),
508             Pair::End(a) => {
509                 punctuated.last = Some(Box::new(a));
510                 nomore = true;
511             }
512         }
513     }
514 }
515 
516 impl<T, P> IntoIterator for Punctuated<T, P> {
517     type Item = T;
518     type IntoIter = IntoIter<T>;
519 
520     fn into_iter(self) -> Self::IntoIter {
521         let mut elements = Vec::with_capacity(self.len());
522         elements.extend(self.inner.into_iter().map(|pair| pair.0));
523         elements.extend(self.last.map(|t| *t));
524 
525         IntoIter {
526             inner: elements.into_iter(),
527         }
528     }
529 }
530 
531 impl<'a, T, P> IntoIterator for &'a Punctuated<T, P> {
532     type Item = &'a T;
533     type IntoIter = Iter<'a, T>;
534 
535     fn into_iter(self) -> Self::IntoIter {
536         Punctuated::iter(self)
537     }
538 }
539 
540 impl<'a, T, P> IntoIterator for &'a mut Punctuated<T, P> {
541     type Item = &'a mut T;
542     type IntoIter = IterMut<'a, T>;
543 
544     fn into_iter(self) -> Self::IntoIter {
545         Punctuated::iter_mut(self)
546     }
547 }
548 
549 impl<T, P> Default for Punctuated<T, P> {
550     fn default() -> Self {
551         Punctuated::new()
552     }
553 }
554 
555 /// An iterator over borrowed pairs of type `Pair<&T, &P>`.
556 ///
557 /// Refer to the [module documentation] for details about punctuated sequences.
558 ///
559 /// [module documentation]: self
560 pub struct Pairs<'a, T: 'a, P: 'a> {
561     inner: slice::Iter<'a, (T, P)>,
562     last: option::IntoIter<&'a T>,
563 }
564 
565 impl<'a, T, P> Iterator for Pairs<'a, T, P> {
566     type Item = Pair<&'a T, &'a P>;
567 
568     fn next(&mut self) -> Option<Self::Item> {
569         self.inner
570             .next()
571             .map(|(t, p)| Pair::Punctuated(t, p))
572             .or_else(|| self.last.next().map(Pair::End))
573     }
574 
575     fn size_hint(&self) -> (usize, Option<usize>) {
576         (self.len(), Some(self.len()))
577     }
578 }
579 
580 impl<'a, T, P> DoubleEndedIterator for Pairs<'a, T, P> {
581     fn next_back(&mut self) -> Option<Self::Item> {
582         self.last
583             .next()
584             .map(Pair::End)
585             .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
586     }
587 }
588 
589 impl<'a, T, P> ExactSizeIterator for Pairs<'a, T, P> {
590     fn len(&self) -> usize {
591         self.inner.len() + self.last.len()
592     }
593 }
594 
595 // No Clone bound on T or P.
596 impl<'a, T, P> Clone for Pairs<'a, T, P> {
597     fn clone(&self) -> Self {
598         Pairs {
599             inner: self.inner.clone(),
600             last: self.last.clone(),
601         }
602     }
603 }
604 
605 /// An iterator over mutably borrowed pairs of type `Pair<&mut T, &mut P>`.
606 ///
607 /// Refer to the [module documentation] for details about punctuated sequences.
608 ///
609 /// [module documentation]: self
610 pub struct PairsMut<'a, T: 'a, P: 'a> {
611     inner: slice::IterMut<'a, (T, P)>,
612     last: option::IntoIter<&'a mut T>,
613 }
614 
615 impl<'a, T, P> Iterator for PairsMut<'a, T, P> {
616     type Item = Pair<&'a mut T, &'a mut P>;
617 
618     fn next(&mut self) -> Option<Self::Item> {
619         self.inner
620             .next()
621             .map(|(t, p)| Pair::Punctuated(t, p))
622             .or_else(|| self.last.next().map(Pair::End))
623     }
624 
625     fn size_hint(&self) -> (usize, Option<usize>) {
626         (self.len(), Some(self.len()))
627     }
628 }
629 
630 impl<'a, T, P> DoubleEndedIterator for PairsMut<'a, T, P> {
631     fn next_back(&mut self) -> Option<Self::Item> {
632         self.last
633             .next()
634             .map(Pair::End)
635             .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
636     }
637 }
638 
639 impl<'a, T, P> ExactSizeIterator for PairsMut<'a, T, P> {
640     fn len(&self) -> usize {
641         self.inner.len() + self.last.len()
642     }
643 }
644 
645 /// An iterator over owned pairs of type `Pair<T, P>`.
646 ///
647 /// Refer to the [module documentation] for details about punctuated sequences.
648 ///
649 /// [module documentation]: self
650 pub struct IntoPairs<T, P> {
651     inner: vec::IntoIter<(T, P)>,
652     last: option::IntoIter<T>,
653 }
654 
655 impl<T, P> Iterator for IntoPairs<T, P> {
656     type Item = Pair<T, P>;
657 
658     fn next(&mut self) -> Option<Self::Item> {
659         self.inner
660             .next()
661             .map(|(t, p)| Pair::Punctuated(t, p))
662             .or_else(|| self.last.next().map(Pair::End))
663     }
664 
665     fn size_hint(&self) -> (usize, Option<usize>) {
666         (self.len(), Some(self.len()))
667     }
668 }
669 
670 impl<T, P> DoubleEndedIterator for IntoPairs<T, P> {
671     fn next_back(&mut self) -> Option<Self::Item> {
672         self.last
673             .next()
674             .map(Pair::End)
675             .or_else(|| self.inner.next_back().map(|(t, p)| Pair::Punctuated(t, p)))
676     }
677 }
678 
679 impl<T, P> ExactSizeIterator for IntoPairs<T, P> {
680     fn len(&self) -> usize {
681         self.inner.len() + self.last.len()
682     }
683 }
684 
685 impl<T, P> Clone for IntoPairs<T, P>
686 where
687     T: Clone,
688     P: Clone,
689 {
690     fn clone(&self) -> Self {
691         IntoPairs {
692             inner: self.inner.clone(),
693             last: self.last.clone(),
694         }
695     }
696 }
697 
698 /// An iterator over owned values of type `T`.
699 ///
700 /// Refer to the [module documentation] for details about punctuated sequences.
701 ///
702 /// [module documentation]: self
703 pub struct IntoIter<T> {
704     inner: vec::IntoIter<T>,
705 }
706 
707 impl<T> Iterator for IntoIter<T> {
708     type Item = T;
709 
710     fn next(&mut self) -> Option<Self::Item> {
711         self.inner.next()
712     }
713 
714     fn size_hint(&self) -> (usize, Option<usize>) {
715         (self.len(), Some(self.len()))
716     }
717 }
718 
719 impl<T> DoubleEndedIterator for IntoIter<T> {
720     fn next_back(&mut self) -> Option<Self::Item> {
721         self.inner.next_back()
722     }
723 }
724 
725 impl<T> ExactSizeIterator for IntoIter<T> {
726     fn len(&self) -> usize {
727         self.inner.len()
728     }
729 }
730 
731 impl<T> Clone for IntoIter<T>
732 where
733     T: Clone,
734 {
735     fn clone(&self) -> Self {
736         IntoIter {
737             inner: self.inner.clone(),
738         }
739     }
740 }
741 
742 /// An iterator over borrowed values of type `&T`.
743 ///
744 /// Refer to the [module documentation] for details about punctuated sequences.
745 ///
746 /// [module documentation]: self
747 pub struct Iter<'a, T: 'a> {
748     inner: Box<NoDrop<dyn IterTrait<'a, T> + 'a>>,
749 }
750 
751 trait IterTrait<'a, T: 'a>: Iterator<Item = &'a T> + DoubleEndedIterator + ExactSizeIterator {
752     fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T> + 'a>>;
753 }
754 
755 struct PrivateIter<'a, T: 'a, P: 'a> {
756     inner: slice::Iter<'a, (T, P)>,
757     last: option::IntoIter<&'a T>,
758 }
759 
760 impl<'a, T, P> TrivialDrop for PrivateIter<'a, T, P>
761 where
762     slice::Iter<'a, (T, P)>: TrivialDrop,
763     option::IntoIter<&'a T>: TrivialDrop,
764 {
765 }
766 
767 #[cfg(any(feature = "full", feature = "derive"))]
768 pub(crate) fn empty_punctuated_iter<'a, T>() -> Iter<'a, T> {
769     Iter {
770         inner: Box::new(NoDrop::new(iter::empty())),
771     }
772 }
773 
774 // No Clone bound on T.
775 impl<'a, T> Clone for Iter<'a, T> {
776     fn clone(&self) -> Self {
777         Iter {
778             inner: self.inner.clone_box(),
779         }
780     }
781 }
782 
783 impl<'a, T> Iterator for Iter<'a, T> {
784     type Item = &'a T;
785 
786     fn next(&mut self) -> Option<Self::Item> {
787         self.inner.next()
788     }
789 
790     fn size_hint(&self) -> (usize, Option<usize>) {
791         (self.len(), Some(self.len()))
792     }
793 }
794 
795 impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
796     fn next_back(&mut self) -> Option<Self::Item> {
797         self.inner.next_back()
798     }
799 }
800 
801 impl<'a, T> ExactSizeIterator for Iter<'a, T> {
802     fn len(&self) -> usize {
803         self.inner.len()
804     }
805 }
806 
807 impl<'a, T, P> Iterator for PrivateIter<'a, T, P> {
808     type Item = &'a T;
809 
810     fn next(&mut self) -> Option<Self::Item> {
811         self.inner
812             .next()
813             .map(|pair| &pair.0)
814             .or_else(|| self.last.next())
815     }
816 }
817 
818 impl<'a, T, P> DoubleEndedIterator for PrivateIter<'a, T, P> {
819     fn next_back(&mut self) -> Option<Self::Item> {
820         self.last
821             .next()
822             .or_else(|| self.inner.next_back().map(|pair| &pair.0))
823     }
824 }
825 
826 impl<'a, T, P> ExactSizeIterator for PrivateIter<'a, T, P> {
827     fn len(&self) -> usize {
828         self.inner.len() + self.last.len()
829     }
830 }
831 
832 // No Clone bound on T or P.
833 impl<'a, T, P> Clone for PrivateIter<'a, T, P> {
834     fn clone(&self) -> Self {
835         PrivateIter {
836             inner: self.inner.clone(),
837             last: self.last.clone(),
838         }
839     }
840 }
841 
842 impl<'a, T, I> IterTrait<'a, T> for I
843 where
844     T: 'a,
845     I: DoubleEndedIterator<Item = &'a T>
846         + ExactSizeIterator<Item = &'a T>
847         + Clone
848         + TrivialDrop
849         + 'a,
850 {
851     fn clone_box(&self) -> Box<NoDrop<dyn IterTrait<'a, T> + 'a>> {
852         Box::new(NoDrop::new(self.clone()))
853     }
854 }
855 
856 /// An iterator over mutably borrowed values of type `&mut T`.
857 ///
858 /// Refer to the [module documentation] for details about punctuated sequences.
859 ///
860 /// [module documentation]: self
861 pub struct IterMut<'a, T: 'a> {
862     inner: Box<NoDrop<dyn IterMutTrait<'a, T, Item = &'a mut T> + 'a>>,
863 }
864 
865 trait IterMutTrait<'a, T: 'a>:
866     DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T>
867 {
868 }
869 
870 struct PrivateIterMut<'a, T: 'a, P: 'a> {
871     inner: slice::IterMut<'a, (T, P)>,
872     last: option::IntoIter<&'a mut T>,
873 }
874 
875 impl<'a, T, P> TrivialDrop for PrivateIterMut<'a, T, P>
876 where
877     slice::IterMut<'a, (T, P)>: TrivialDrop,
878     option::IntoIter<&'a mut T>: TrivialDrop,
879 {
880 }
881 
882 #[cfg(any(feature = "full", feature = "derive"))]
883 pub(crate) fn empty_punctuated_iter_mut<'a, T>() -> IterMut<'a, T> {
884     IterMut {
885         inner: Box::new(NoDrop::new(iter::empty())),
886     }
887 }
888 
889 impl<'a, T> Iterator for IterMut<'a, T> {
890     type Item = &'a mut T;
891 
892     fn next(&mut self) -> Option<Self::Item> {
893         self.inner.next()
894     }
895 
896     fn size_hint(&self) -> (usize, Option<usize>) {
897         (self.len(), Some(self.len()))
898     }
899 }
900 
901 impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
902     fn next_back(&mut self) -> Option<Self::Item> {
903         self.inner.next_back()
904     }
905 }
906 
907 impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
908     fn len(&self) -> usize {
909         self.inner.len()
910     }
911 }
912 
913 impl<'a, T, P> Iterator for PrivateIterMut<'a, T, P> {
914     type Item = &'a mut T;
915 
916     fn next(&mut self) -> Option<Self::Item> {
917         self.inner
918             .next()
919             .map(|pair| &mut pair.0)
920             .or_else(|| self.last.next())
921     }
922 }
923 
924 impl<'a, T, P> DoubleEndedIterator for PrivateIterMut<'a, T, P> {
925     fn next_back(&mut self) -> Option<Self::Item> {
926         self.last
927             .next()
928             .or_else(|| self.inner.next_back().map(|pair| &mut pair.0))
929     }
930 }
931 
932 impl<'a, T, P> ExactSizeIterator for PrivateIterMut<'a, T, P> {
933     fn len(&self) -> usize {
934         self.inner.len() + self.last.len()
935     }
936 }
937 
938 impl<'a, T, I> IterMutTrait<'a, T> for I
939 where
940     T: 'a,
941     I: DoubleEndedIterator<Item = &'a mut T> + ExactSizeIterator<Item = &'a mut T> + 'a,
942 {
943 }
944 
945 /// A single syntax tree node of type `T` followed by its trailing punctuation
946 /// of type `P` if any.
947 ///
948 /// Refer to the [module documentation] for details about punctuated sequences.
949 ///
950 /// [module documentation]: self
951 pub enum Pair<T, P> {
952     Punctuated(T, P),
953     End(T),
954 }
955 
956 impl<T, P> Pair<T, P> {
957     /// Extracts the syntax tree node from this punctuated pair, discarding the
958     /// following punctuation.
959     pub fn into_value(self) -> T {
960         match self {
961             Pair::Punctuated(t, _) | Pair::End(t) => t,
962         }
963     }
964 
965     /// Borrows the syntax tree node from this punctuated pair.
966     pub fn value(&self) -> &T {
967         match self {
968             Pair::Punctuated(t, _) | Pair::End(t) => t,
969         }
970     }
971 
972     /// Mutably borrows the syntax tree node from this punctuated pair.
973     pub fn value_mut(&mut self) -> &mut T {
974         match self {
975             Pair::Punctuated(t, _) | Pair::End(t) => t,
976         }
977     }
978 
979     /// Borrows the punctuation from this punctuated pair, unless this pair is
980     /// the final one and there is no trailing punctuation.
981     pub fn punct(&self) -> Option<&P> {
982         match self {
983             Pair::Punctuated(_, p) => Some(p),
984             Pair::End(_) => None,
985         }
986     }
987 
988     /// Mutably borrows the punctuation from this punctuated pair, unless the
989     /// pair is the final one and there is no trailing punctuation.
990     ///
991     /// # Example
992     ///
993     /// ```
994     /// # use proc_macro2::Span;
995     /// # use syn::punctuated::Punctuated;
996     /// # use syn::{parse_quote, Token, TypeParamBound};
997     /// #
998     /// # let mut punctuated = Punctuated::<TypeParamBound, Token![+]>::new();
999     /// # let span = Span::call_site();
1000     /// #
1001     /// punctuated.insert(0, parse_quote!('lifetime));
1002     /// if let Some(punct) = punctuated.pairs_mut().next().unwrap().punct_mut() {
1003     ///     punct.span = span;
1004     /// }
1005     /// ```
1006     pub fn punct_mut(&mut self) -> Option<&mut P> {
1007         match self {
1008             Pair::Punctuated(_, p) => Some(p),
1009             Pair::End(_) => None,
1010         }
1011     }
1012 
1013     /// Creates a punctuated pair out of a syntax tree node and an optional
1014     /// following punctuation.
1015     pub fn new(t: T, p: Option<P>) -> Self {
1016         match p {
1017             Some(p) => Pair::Punctuated(t, p),
1018             None => Pair::End(t),
1019         }
1020     }
1021 
1022     /// Produces this punctuated pair as a tuple of syntax tree node and
1023     /// optional following punctuation.
1024     pub fn into_tuple(self) -> (T, Option<P>) {
1025         match self {
1026             Pair::Punctuated(t, p) => (t, Some(p)),
1027             Pair::End(t) => (t, None),
1028         }
1029     }
1030 }
1031 
1032 #[cfg(feature = "clone-impls")]
1033 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
1034 impl<T, P> Pair<&T, &P> {
1035     pub fn cloned(self) -> Pair<T, P>
1036     where
1037         T: Clone,
1038         P: Clone,
1039     {
1040         match self {
1041             Pair::Punctuated(t, p) => Pair::Punctuated(t.clone(), p.clone()),
1042             Pair::End(t) => Pair::End(t.clone()),
1043         }
1044     }
1045 }
1046 
1047 #[cfg(feature = "clone-impls")]
1048 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
1049 impl<T, P> Clone for Pair<T, P>
1050 where
1051     T: Clone,
1052     P: Clone,
1053 {
1054     fn clone(&self) -> Self {
1055         match self {
1056             Pair::Punctuated(t, p) => Pair::Punctuated(t.clone(), p.clone()),
1057             Pair::End(t) => Pair::End(t.clone()),
1058         }
1059     }
1060 }
1061 
1062 #[cfg(feature = "clone-impls")]
1063 #[cfg_attr(docsrs, doc(cfg(feature = "clone-impls")))]
1064 impl<T, P> Copy for Pair<T, P>
1065 where
1066     T: Copy,
1067     P: Copy,
1068 {
1069 }
1070 
1071 impl<T, P> Index<usize> for Punctuated<T, P> {
1072     type Output = T;
1073 
1074     fn index(&self, index: usize) -> &Self::Output {
1075         if index == self.len() - 1 {
1076             match &self.last {
1077                 Some(t) => t,
1078                 None => &self.inner[index].0,
1079             }
1080         } else {
1081             &self.inner[index].0
1082         }
1083     }
1084 }
1085 
1086 impl<T, P> IndexMut<usize> for Punctuated<T, P> {
1087     fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1088         if index == self.len() - 1 {
1089             match &mut self.last {
1090                 Some(t) => t,
1091                 None => &mut self.inner[index].0,
1092             }
1093         } else {
1094             &mut self.inner[index].0
1095         }
1096     }
1097 }
1098 
1099 #[cfg(all(feature = "fold", any(feature = "full", feature = "derive")))]
1100 pub(crate) fn fold<T, P, V, F>(
1101     punctuated: Punctuated<T, P>,
1102     fold: &mut V,
1103     mut f: F,
1104 ) -> Punctuated<T, P>
1105 where
1106     V: ?Sized,
1107     F: FnMut(&mut V, T) -> T,
1108 {
1109     Punctuated {
1110         inner: punctuated
1111             .inner
1112             .into_iter()
1113             .map(|(t, p)| (f(fold, t), p))
1114             .collect(),
1115         last: match punctuated.last {
1116             Some(t) => Some(Box::new(f(fold, *t))),
1117             None => None,
1118         },
1119     }
1120 }
1121 
1122 #[cfg(feature = "printing")]
1123 mod printing {
1124     use crate::punctuated::{Pair, Punctuated};
1125     use proc_macro2::TokenStream;
1126     use quote::{ToTokens, TokenStreamExt};
1127 
1128     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1129     impl<T, P> ToTokens for Punctuated<T, P>
1130     where
1131         T: ToTokens,
1132         P: ToTokens,
1133     {
1134         fn to_tokens(&self, tokens: &mut TokenStream) {
1135             tokens.append_all(self.pairs());
1136         }
1137     }
1138 
1139     #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
1140     impl<T, P> ToTokens for Pair<T, P>
1141     where
1142         T: ToTokens,
1143         P: ToTokens,
1144     {
1145         fn to_tokens(&self, tokens: &mut TokenStream) {
1146             match self {
1147                 Pair::Punctuated(a, b) => {
1148                     a.to_tokens(tokens);
1149                     b.to_tokens(tokens);
1150                 }
1151                 Pair::End(a) => a.to_tokens(tokens),
1152             }
1153         }
1154     }
1155 }
1156