@@ -1714,11 +1714,10 @@ impl<'a> Parser<'a> {
1714
1714
} else if self . eat_keyword ( keywords:: Const ) {
1715
1715
Mutability :: Immutable
1716
1716
} else {
1717
- let span = self . prev_span ;
1718
- self . span_err ( span,
1719
- "expected mut or const in raw pointer type (use \
1720
- `*mut T` or `*const T` as appropriate)") ;
1721
- Mutability :: Immutable
1717
+ let mut err = self . fatal ( "expected mut or const in raw pointer type (use \
1718
+ `*mut T` or `*const T` as appropriate)") ;
1719
+ err. span_label ( self . prev_span , "expected mut or const" ) ;
1720
+ return Err ( err) ;
1722
1721
} ;
1723
1722
let t = self . parse_ty_no_plus ( ) ?;
1724
1723
Ok ( MutTy { ty : t, mutbl : mutbl } )
@@ -2022,20 +2021,31 @@ impl<'a> Parser<'a> {
2022
2021
-> PResult < ' a , PathSegment > {
2023
2022
let ident = self . parse_path_segment_ident ( ) ?;
2024
2023
2025
- let is_args_start = |token : & token:: Token | match * token {
2026
- token:: Lt | token:: BinOp ( token:: Shl ) | token:: OpenDelim ( token:: Paren ) => true ,
2024
+ let is_args_start = |token : & token:: Token , include_paren : bool | match * token {
2025
+ token:: Lt | token:: BinOp ( token:: Shl ) => true ,
2026
+ token:: OpenDelim ( token:: Paren ) => include_paren,
2027
2027
_ => false ,
2028
2028
} ;
2029
- let check_args_start = |this : & mut Self | {
2030
- this. expected_tokens . extend_from_slice (
2031
- & [ TokenType :: Token ( token:: Lt ) , TokenType :: Token ( token:: OpenDelim ( token:: Paren ) ) ]
2032
- ) ;
2033
- is_args_start ( & this. token )
2029
+ let check_args_start = |this : & mut Self , include_paren : bool | {
2030
+ this. expected_tokens . push ( TokenType :: Token ( token:: Lt ) ) ;
2031
+ if include_paren {
2032
+ this. expected_tokens . push ( TokenType :: Token ( token:: OpenDelim ( token:: Paren ) ) ) ;
2033
+ }
2034
+ is_args_start ( & this. token , include_paren)
2034
2035
} ;
2035
2036
2036
- Ok ( if style == PathStyle :: Type && check_args_start ( self ) ||
2037
- style != PathStyle :: Mod && self . check ( & token:: ModSep )
2038
- && self . look_ahead ( 1 , |t| is_args_start ( t) ) {
2037
+ let mut parser_snapshot_before_generics = None ;
2038
+
2039
+ Ok ( if style == PathStyle :: Type && check_args_start ( self , true )
2040
+ || style != PathStyle :: Mod && self . check ( & token:: ModSep )
2041
+ && self . look_ahead ( 1 , |t| is_args_start ( t, true ) )
2042
+ || style == PathStyle :: Expr && check_args_start ( self , false ) && {
2043
+ // Check for generic arguments in an expression without a disambiguating `::`.
2044
+ // We have to save a snapshot, because it could end up being an expression
2045
+ // instead.
2046
+ parser_snapshot_before_generics = Some ( self . clone ( ) ) ;
2047
+ true
2048
+ } {
2039
2049
// Generic arguments are found - `<`, `(`, `::<` or `::(`.
2040
2050
let lo = self . span ;
2041
2051
if self . eat ( & token:: ModSep ) && style == PathStyle :: Type && enable_warning {
@@ -2045,10 +2055,26 @@ impl<'a> Parser<'a> {
2045
2055
2046
2056
let args = if self . eat_lt ( ) {
2047
2057
// `<'a, T, A = U>`
2048
- let ( args, bindings) = self . parse_generic_args ( ) ?;
2049
- self . expect_gt ( ) ?;
2050
- let span = lo. to ( self . prev_span ) ;
2051
- AngleBracketedArgs { args, bindings, span } . into ( )
2058
+ let args: PResult < _ > = do catch {
2059
+ let ( args, bindings) = self . parse_generic_args ( ) ?;
2060
+ self . expect_gt ( ) ?;
2061
+ let span = lo. to ( self . prev_span ) ;
2062
+ AngleBracketedArgs { args, bindings, span }
2063
+ } ;
2064
+
2065
+ match args {
2066
+ Err ( mut err) => {
2067
+ if let Some ( snapshot) = parser_snapshot_before_generics {
2068
+ err. cancel ( ) ;
2069
+ mem:: replace ( self , snapshot) ;
2070
+ return Ok ( PathSegment :: from_ident ( ident) ) ;
2071
+ }
2072
+ return Err ( err) ;
2073
+ }
2074
+ _ => {
2075
+ args?. into ( )
2076
+ }
2077
+ }
2052
2078
} else {
2053
2079
// `(T, U) -> R`
2054
2080
self . bump ( ) ; // `(`
0 commit comments