@@ -1714,11 +1714,10 @@ impl<'a> Parser<'a> {
17141714 } else if self . eat_keyword ( keywords:: Const ) {
17151715 Mutability :: Immutable
17161716 } 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) ;
17221721 } ;
17231722 let t = self . parse_ty_no_plus ( ) ?;
17241723 Ok ( MutTy { ty : t, mutbl : mutbl } )
@@ -2022,20 +2021,31 @@ impl<'a> Parser<'a> {
20222021 -> PResult < ' a , PathSegment > {
20232022 let ident = self . parse_path_segment_ident ( ) ?;
20242023
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,
20272027 _ => false ,
20282028 } ;
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)
20342035 } ;
20352036
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+ } {
20392049 // Generic arguments are found - `<`, `(`, `::<` or `::(`.
20402050 let lo = self . span ;
20412051 if self . eat ( & token:: ModSep ) && style == PathStyle :: Type && enable_warning {
@@ -2045,10 +2055,26 @@ impl<'a> Parser<'a> {
20452055
20462056 let args = if self . eat_lt ( ) {
20472057 // `<'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+ }
20522078 } else {
20532079 // `(T, U) -> R`
20542080 self . bump ( ) ; // `(`
0 commit comments