@@ -44,6 +44,7 @@ mod diagnostic;
4444mod escape;
4545mod to_tokens;
4646
47+ use core:: ops:: BitOr ;
4748use std:: ffi:: CStr ;
4849use std:: ops:: { Range , RangeBounds } ;
4950use std:: path:: PathBuf ;
@@ -1613,3 +1614,196 @@ pub mod tracked_path {
16131614 crate :: bridge:: client:: FreeFunctions :: track_path ( path) ;
16141615 }
16151616}
1617+
1618+ #[ doc( hidden) ]
1619+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1620+ #[ derive( Debug ) ]
1621+ pub struct HasIterator ;
1622+ #[ doc( hidden) ]
1623+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1624+ #[ derive( Debug ) ]
1625+ pub struct ThereIsNoIteratorInRepetition ;
1626+
1627+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1628+ impl BitOr < ThereIsNoIteratorInRepetition > for ThereIsNoIteratorInRepetition {
1629+ type Output = ThereIsNoIteratorInRepetition ;
1630+ fn bitor ( self , _rhs : ThereIsNoIteratorInRepetition ) -> ThereIsNoIteratorInRepetition {
1631+ ThereIsNoIteratorInRepetition
1632+ }
1633+ }
1634+
1635+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1636+ impl BitOr < ThereIsNoIteratorInRepetition > for HasIterator {
1637+ type Output = HasIterator ;
1638+ fn bitor ( self , _rhs : ThereIsNoIteratorInRepetition ) -> HasIterator {
1639+ HasIterator
1640+ }
1641+ }
1642+
1643+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1644+ impl BitOr < HasIterator > for ThereIsNoIteratorInRepetition {
1645+ type Output = HasIterator ;
1646+ fn bitor ( self , _rhs : HasIterator ) -> HasIterator {
1647+ HasIterator
1648+ }
1649+ }
1650+
1651+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1652+ impl BitOr < HasIterator > for HasIterator {
1653+ type Output = HasIterator ;
1654+ fn bitor ( self , _rhs : HasIterator ) -> HasIterator {
1655+ HasIterator
1656+ }
1657+ }
1658+
1659+ /// Extension traits used by the implementation of `quote!`. These are defined
1660+ /// in separate traits, rather than as a single trait due to ambiguity issues.
1661+ ///
1662+ /// These traits expose a `quote_into_iter` method which should allow calling
1663+ /// whichever impl happens to be applicable. Calling that method repeatedly on
1664+ /// the returned value should be idempotent.
1665+ #[ doc( hidden) ]
1666+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1667+ pub mod ext {
1668+ use std:: collections:: btree_set:: { self , BTreeSet } ;
1669+ use std:: slice;
1670+
1671+ use super :: {
1672+ HasIterator as HasIter , RepInterp , ThereIsNoIteratorInRepetition as DoesNotHaveIter ,
1673+ } ;
1674+ use crate :: ToTokens ;
1675+
1676+ /// Extension trait providing the `quote_into_iter` method on iterators.
1677+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1678+ pub trait RepIteratorExt : Iterator + Sized {
1679+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1680+ fn quote_into_iter ( self ) -> ( Self , HasIter ) {
1681+ ( self , HasIter )
1682+ }
1683+ }
1684+
1685+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1686+ impl < T : Iterator > RepIteratorExt for T { }
1687+
1688+ /// Extension trait providing the `quote_into_iter` method for
1689+ /// non-iterable types. These types interpolate the same value in each
1690+ /// iteration of the repetition.
1691+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1692+ pub trait RepToTokensExt {
1693+ /// Pretend to be an iterator for the purposes of `quote_into_iter`.
1694+ /// This allows repeated calls to `quote_into_iter` to continue
1695+ /// correctly returning DoesNotHaveIter.
1696+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1697+ fn next ( & self ) -> Option < & Self > {
1698+ Some ( self )
1699+ }
1700+
1701+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1702+ fn quote_into_iter ( & self ) -> ( & Self , DoesNotHaveIter ) {
1703+ ( self , DoesNotHaveIter )
1704+ }
1705+ }
1706+
1707+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1708+ impl < T : ToTokens + ?Sized > RepToTokensExt for T { }
1709+
1710+ /// Extension trait providing the `quote_into_iter` method for types that
1711+ /// can be referenced as an iterator.
1712+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1713+ pub trait RepAsIteratorExt < ' q > {
1714+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1715+ type Iter : Iterator ;
1716+
1717+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1718+ fn quote_into_iter ( & ' q self ) -> ( Self :: Iter , HasIter ) ;
1719+ }
1720+
1721+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1722+ impl < ' q , ' a , T : RepAsIteratorExt < ' q > + ?Sized > RepAsIteratorExt < ' q > for & ' a T {
1723+ type Iter = T :: Iter ;
1724+
1725+ fn quote_into_iter ( & ' q self ) -> ( Self :: Iter , HasIter ) {
1726+ <T as RepAsIteratorExt >:: quote_into_iter ( * self )
1727+ }
1728+ }
1729+
1730+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1731+ impl < ' q , ' a , T : RepAsIteratorExt < ' q > + ?Sized > RepAsIteratorExt < ' q > for & ' a mut T {
1732+ type Iter = T :: Iter ;
1733+
1734+ fn quote_into_iter ( & ' q self ) -> ( Self :: Iter , HasIter ) {
1735+ <T as RepAsIteratorExt >:: quote_into_iter ( * self )
1736+ }
1737+ }
1738+
1739+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1740+ impl < ' q , T : ' q > RepAsIteratorExt < ' q > for [ T ] {
1741+ type Iter = slice:: Iter < ' q , T > ;
1742+
1743+ fn quote_into_iter ( & ' q self ) -> ( Self :: Iter , HasIter ) {
1744+ ( self . iter ( ) , HasIter )
1745+ }
1746+ }
1747+
1748+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1749+ impl < ' q , T : ' q > RepAsIteratorExt < ' q > for Vec < T > {
1750+ type Iter = slice:: Iter < ' q , T > ;
1751+
1752+ fn quote_into_iter ( & ' q self ) -> ( Self :: Iter , HasIter ) {
1753+ ( self . iter ( ) , HasIter )
1754+ }
1755+ }
1756+
1757+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1758+ impl < ' q , T : ' q > RepAsIteratorExt < ' q > for BTreeSet < T > {
1759+ type Iter = btree_set:: Iter < ' q , T > ;
1760+
1761+ fn quote_into_iter ( & ' q self ) -> ( Self :: Iter , HasIter ) {
1762+ ( self . iter ( ) , HasIter )
1763+ }
1764+ }
1765+
1766+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1767+ impl < ' q , T : RepAsIteratorExt < ' q > > RepAsIteratorExt < ' q > for RepInterp < T > {
1768+ type Iter = T :: Iter ;
1769+
1770+ fn quote_into_iter ( & ' q self ) -> ( Self :: Iter , HasIter ) {
1771+ self . 0 . quote_into_iter ( )
1772+ }
1773+ }
1774+ }
1775+
1776+ // Helper type used within interpolations to allow for repeated binding names.
1777+ // Implements the relevant traits, and exports a dummy `next()` method.
1778+ #[ derive( Copy , Clone ) ]
1779+ #[ doc( hidden) ]
1780+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1781+ pub struct RepInterp < T > ( pub T ) ;
1782+
1783+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1784+ impl < T > RepInterp < T > {
1785+ // This method is intended to look like `Iterator::next`, and is called when
1786+ // a name is bound multiple times, as the previous binding will shadow the
1787+ // original `Iterator` object. This allows us to avoid advancing the
1788+ // iterator multiple times per iteration.
1789+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1790+ pub fn next ( self ) -> Option < T > {
1791+ Some ( self . 0 )
1792+ }
1793+ }
1794+
1795+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1796+ impl < T : Iterator > Iterator for RepInterp < T > {
1797+ type Item = T :: Item ;
1798+
1799+ fn next ( & mut self ) -> Option < Self :: Item > {
1800+ self . 0 . next ( )
1801+ }
1802+ }
1803+
1804+ #[ unstable( feature = "proc_macro_quote" , issue = "54722" ) ]
1805+ impl < T : ToTokens > ToTokens for RepInterp < T > {
1806+ fn to_tokens ( & self , tokens : & mut TokenStream ) {
1807+ self . 0 . to_tokens ( tokens) ;
1808+ }
1809+ }
0 commit comments