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