@@ -1706,50 +1706,18 @@ impl<'a> Parser<'a> {
1706
1706
// Parse any number of segments and bound sets. A segment is an
1707
1707
// identifier followed by an optional lifetime and a set of types.
1708
1708
// A bound set is a set of type parameter bounds.
1709
- let mut segments = Vec :: new ( ) ;
1710
- loop {
1711
- // First, parse an identifier.
1712
- let identifier = self . parse_ident ( ) ;
1713
-
1714
- // Parse the '::' before type parameters if it's required. If
1715
- // it is required and wasn't present, then we're done.
1716
- if mode == LifetimeAndTypesWithColons &&
1717
- !self . eat ( & token:: ModSep ) {
1718
- segments. push ( ast:: PathSegment {
1719
- identifier : identifier,
1720
- lifetimes : Vec :: new ( ) ,
1721
- types : OwnedSlice :: empty ( ) ,
1722
- } ) ;
1723
- break
1709
+ let segments = match mode {
1710
+ LifetimeAndTypesWithoutColons |
1711
+ LifetimeAndTypesAndBounds => {
1712
+ self . parse_path_segments_without_colons ( )
1724
1713
}
1725
-
1726
- // Parse the `<` before the lifetime and types, if applicable.
1727
- let ( any_lifetime_or_types, lifetimes, types) = {
1728
- if mode != NoTypesAllowed && self . eat_lt ( false ) {
1729
- let ( lifetimes, types) =
1730
- self . parse_generic_values_after_lt ( ) ;
1731
- ( true , lifetimes, OwnedSlice :: from_vec ( types) )
1732
- } else {
1733
- ( false , Vec :: new ( ) , OwnedSlice :: empty ( ) )
1734
- }
1735
- } ;
1736
-
1737
- // Assemble and push the result.
1738
- segments. push ( ast:: PathSegment {
1739
- identifier : identifier,
1740
- lifetimes : lifetimes,
1741
- types : types,
1742
- } ) ;
1743
-
1744
- // We're done if we don't see a '::', unless the mode required
1745
- // a double colon to get here in the first place.
1746
- if !( mode == LifetimeAndTypesWithColons &&
1747
- !any_lifetime_or_types) {
1748
- if !self . eat ( & token:: ModSep ) {
1749
- break
1750
- }
1714
+ LifetimeAndTypesWithColons => {
1715
+ self . parse_path_segments_with_colons ( )
1751
1716
}
1752
- }
1717
+ NoTypesAllowed => {
1718
+ self . parse_path_segments_without_types ( )
1719
+ }
1720
+ } ;
1753
1721
1754
1722
// Next, parse a plus and bounded type parameters, if
1755
1723
// applicable. We need to remember whether the separate was
@@ -1792,6 +1760,104 @@ impl<'a> Parser<'a> {
1792
1760
}
1793
1761
}
1794
1762
1763
+ /// Examples:
1764
+ /// - `a::b<T,U>::c<V,W>`
1765
+ /// - `a::b<T,U>::c(V) -> W`
1766
+ /// - `a::b<T,U>::c(V)`
1767
+ pub fn parse_path_segments_without_colons ( & mut self ) -> Vec < ast:: PathSegment > {
1768
+ let mut segments = Vec :: new ( ) ;
1769
+ loop {
1770
+ // First, parse an identifier.
1771
+ let identifier = self . parse_ident ( ) ;
1772
+
1773
+ // Parse types, optionally.
1774
+ let ( lifetimes, types) = if self . eat_lt ( false ) {
1775
+ self . parse_generic_values_after_lt ( )
1776
+ } else if false && self . eat ( & token:: LParen ) {
1777
+ let mut types = self . parse_seq_to_end (
1778
+ & token:: RParen ,
1779
+ seq_sep_trailing_allowed ( token:: Comma ) ,
1780
+ |p| p. parse_ty ( true ) ) ;
1781
+
1782
+ if self . eat ( & token:: RArrow ) {
1783
+ types. push ( self . parse_ty ( true ) )
1784
+ }
1785
+
1786
+ ( Vec :: new ( ) , types)
1787
+ } else {
1788
+ ( Vec :: new ( ) , Vec :: new ( ) )
1789
+ } ;
1790
+
1791
+ // Assemble and push the result.
1792
+ segments. push ( ast:: PathSegment { identifier : identifier,
1793
+ lifetimes : lifetimes,
1794
+ types : OwnedSlice :: from_vec ( types) , } ) ;
1795
+
1796
+ // Continue only if we see a `::`
1797
+ if !self . eat ( & token:: ModSep ) {
1798
+ return segments;
1799
+ }
1800
+ }
1801
+ }
1802
+
1803
+ /// Examples:
1804
+ /// - `a::b::<T,U>::c`
1805
+ pub fn parse_path_segments_with_colons ( & mut self ) -> Vec < ast:: PathSegment > {
1806
+ let mut segments = Vec :: new ( ) ;
1807
+ loop {
1808
+ // First, parse an identifier.
1809
+ let identifier = self . parse_ident ( ) ;
1810
+
1811
+ // If we do not see a `::`, stop.
1812
+ if !self . eat ( & token:: ModSep ) {
1813
+ segments. push ( ast:: PathSegment { identifier : identifier,
1814
+ lifetimes : Vec :: new ( ) ,
1815
+ types : OwnedSlice :: empty ( ) } ) ;
1816
+ return segments;
1817
+ }
1818
+
1819
+ // Check for a type segment.
1820
+ if self . eat_lt ( false ) {
1821
+ // Consumed `a::b::<`, go look for types
1822
+ let ( lifetimes, types) = self . parse_generic_values_after_lt ( ) ;
1823
+ segments. push ( ast:: PathSegment { identifier : identifier,
1824
+ lifetimes : lifetimes,
1825
+ types : OwnedSlice :: from_vec ( types) } ) ;
1826
+
1827
+ // Consumed `a::b::<T,U>`, check for `::` before proceeding
1828
+ if !self . eat ( & token:: ModSep ) {
1829
+ return segments;
1830
+ }
1831
+ } else {
1832
+ // Consumed `a::`, go look for `b`
1833
+ segments. push ( ast:: PathSegment { identifier : identifier,
1834
+ lifetimes : Vec :: new ( ) ,
1835
+ types : OwnedSlice :: empty ( ) } ) ;
1836
+ }
1837
+ }
1838
+ }
1839
+
1840
+
1841
+ /// Examples:
1842
+ /// - `a::b::c`
1843
+ pub fn parse_path_segments_without_types ( & mut self ) -> Vec < ast:: PathSegment > {
1844
+ let mut segments = Vec :: new ( ) ;
1845
+ loop {
1846
+ // First, parse an identifier.
1847
+ let identifier = self . parse_ident ( ) ;
1848
+
1849
+ // Assemble and push the result.
1850
+ segments. push ( ast:: PathSegment { identifier : identifier,
1851
+ lifetimes : Vec :: new ( ) ,
1852
+ types : OwnedSlice :: empty ( ) , } ) ;
1853
+
1854
+ // If we do not see a `::`, stop.
1855
+ if !self . eat ( & token:: ModSep ) {
1856
+ return segments;
1857
+ }
1858
+ }
1859
+ }
1860
+
1795
1861
/// parses 0 or 1 lifetime
1796
1862
pub fn parse_opt_lifetime ( & mut self ) -> Option < ast:: Lifetime > {
1797
1863
match self . token {
0 commit comments