@@ -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 } )
@@ -1984,20 +1983,26 @@ impl<'a> Parser<'a> {
19841983 -> PResult < ' a , PathSegment > {
19851984 let ident = self . parse_path_segment_ident ( ) ?;
19861985
1987- let is_args_start = |token : & token:: Token | match * token {
1988- token:: Lt | token:: BinOp ( token:: Shl ) | token:: OpenDelim ( token:: Paren ) => true ,
1986+ let is_args_start = |token : & token:: Token , include_paren : bool | match * token {
1987+ token:: Lt | token:: BinOp ( token:: Shl ) => true ,
1988+ token:: OpenDelim ( token:: Paren ) => include_paren,
19891989 _ => false ,
19901990 } ;
1991- let check_args_start = |this : & mut Self | {
1992- this. expected_tokens . extend_from_slice (
1993- & [ TokenType :: Token ( token:: Lt ) , TokenType :: Token ( token:: OpenDelim ( token:: Paren ) ) ]
1994- ) ;
1995- is_args_start ( & this. token )
1991+ let check_args_start = |this : & mut Self , include_paren : bool | {
1992+ this. expected_tokens . push ( TokenType :: Token ( token:: Lt ) ) ;
1993+ if include_paren {
1994+ this. expected_tokens . push ( TokenType :: Token ( token:: OpenDelim ( token:: Paren ) ) ) ;
1995+ }
1996+ is_args_start ( & this. token , include_paren)
19961997 } ;
19971998
1998- Ok ( if style == PathStyle :: Type && check_args_start ( self ) ||
1999+ let expr_without_disambig = style == PathStyle :: Expr && check_args_start ( self , false ) ;
2000+ let parser_snapshot_before_generics = self . clone ( ) ;
2001+
2002+ Ok ( if style == PathStyle :: Type && check_args_start ( self , true ) ||
19992003 style != PathStyle :: Mod && self . check ( & token:: ModSep )
2000- && self . look_ahead ( 1 , |t| is_args_start ( t) ) {
2004+ && self . look_ahead ( 1 , |t| is_args_start ( t, true ) )
2005+ || expr_without_disambig {
20012006 // Generic arguments are found - `<`, `(`, `::<` or `::(`.
20022007 let lo = self . span ;
20032008 if self . eat ( & token:: ModSep ) && style == PathStyle :: Type && enable_warning {
@@ -2007,10 +2012,26 @@ impl<'a> Parser<'a> {
20072012
20082013 let args = if self . eat_lt ( ) {
20092014 // `<'a, T, A = U>`
2010- let ( args, bindings) = self . parse_generic_args ( ) ?;
2011- self . expect_gt ( ) ?;
2012- let span = lo. to ( self . prev_span ) ;
2013- AngleBracketedArgs { args, bindings, span } . into ( )
2015+ let args: PResult < _ > = do catch {
2016+ let ( args, bindings) = self . parse_generic_args ( ) ?;
2017+ self . expect_gt ( ) ?;
2018+ let span = lo. to ( self . prev_span ) ;
2019+ AngleBracketedArgs { args, bindings, span }
2020+ } ;
2021+
2022+ match args {
2023+ Err ( mut err) => {
2024+ if expr_without_disambig {
2025+ err. cancel ( ) ;
2026+ mem:: replace ( self , parser_snapshot_before_generics) ;
2027+ return Ok ( PathSegment :: from_ident ( ident) ) ;
2028+ }
2029+ return Err ( err) ;
2030+ }
2031+ _ => {
2032+ args?. into ( )
2033+ }
2034+ }
20142035 } else {
20152036 // `(T, U) -> R`
20162037 self . bump ( ) ; // `(`
0 commit comments