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