@@ -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,26 @@ 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+ let expr_without_disambig = style == PathStyle :: Expr && check_args_start ( self , false ) ;
2038+ let parser_snapshot_before_generics = self . clone ( ) ;
2039+
2040+ Ok ( if style == PathStyle :: Type && check_args_start ( self , true ) ||
20372041 style != PathStyle :: Mod && self . check ( & token:: ModSep )
2038- && self . look_ahead ( 1 , |t| is_args_start ( t) ) {
2042+ && self . look_ahead ( 1 , |t| is_args_start ( t, true ) )
2043+ || expr_without_disambig {
20392044 // Generic arguments are found - `<`, `(`, `::<` or `::(`.
20402045 let lo = self . span ;
20412046 if self . eat ( & token:: ModSep ) && style == PathStyle :: Type && enable_warning {
@@ -2045,10 +2050,26 @@ impl<'a> Parser<'a> {
20452050
20462051 let args = if self . eat_lt ( ) {
20472052 // `<'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 ( )
2053+ let args: PResult < _ > = do catch {
2054+ let ( args, bindings) = self . parse_generic_args ( ) ?;
2055+ self . expect_gt ( ) ?;
2056+ let span = lo. to ( self . prev_span ) ;
2057+ AngleBracketedArgs { args, bindings, span }
2058+ } ;
2059+
2060+ match args {
2061+ Err ( mut err) => {
2062+ if expr_without_disambig {
2063+ err. cancel ( ) ;
2064+ mem:: replace ( self , parser_snapshot_before_generics) ;
2065+ return Ok ( PathSegment :: from_ident ( ident) ) ;
2066+ }
2067+ return Err ( err) ;
2068+ }
2069+ _ => {
2070+ args?. into ( )
2071+ }
2072+ }
20522073 } else {
20532074 // `(T, U) -> R`
20542075 self . bump ( ) ; // `(`
0 commit comments