@@ -1725,11 +1725,10 @@ impl<'a> Parser<'a> {
1725
1725
} else if self . eat_keyword ( keywords:: Const ) {
1726
1726
Mutability :: Immutable
1727
1727
} else {
1728
- let span = self . prev_span ;
1729
- self . span_err ( span,
1730
- "expected mut or const in raw pointer type (use \
1731
- `*mut T` or `*const T` as appropriate)") ;
1732
- Mutability :: Immutable
1728
+ let mut err = self . fatal ( "expected mut or const in raw pointer type (use \
1729
+ `*mut T` or `*const T` as appropriate)") ;
1730
+ err. span_label ( self . prev_span , "expected mut or const" ) ;
1731
+ return Err ( err) ;
1733
1732
} ;
1734
1733
let t = self . parse_ty_no_plus ( ) ?;
1735
1734
Ok ( MutTy { ty : t, mutbl : mutbl } )
@@ -2041,20 +2040,26 @@ impl<'a> Parser<'a> {
2041
2040
-> PResult < ' a , PathSegment > {
2042
2041
let ident = self . parse_path_segment_ident ( ) ?;
2043
2042
2044
- let is_args_start = |token : & token:: Token | match * token {
2045
- token:: Lt | token:: BinOp ( token:: Shl ) | token:: OpenDelim ( token:: Paren ) => true ,
2043
+ let is_args_start = |token : & token:: Token , include_paren : bool | match * token {
2044
+ token:: Lt | token:: BinOp ( token:: Shl ) => true ,
2045
+ token:: OpenDelim ( token:: Paren ) => include_paren,
2046
2046
_ => false ,
2047
2047
} ;
2048
- let check_args_start = |this : & mut Self | {
2049
- this. expected_tokens . extend_from_slice (
2050
- & [ TokenType :: Token ( token:: Lt ) , TokenType :: Token ( token:: OpenDelim ( token:: Paren ) ) ]
2051
- ) ;
2052
- is_args_start ( & this. token )
2048
+ let check_args_start = |this : & mut Self , include_paren : bool | {
2049
+ this. expected_tokens . push ( TokenType :: Token ( token:: Lt ) ) ;
2050
+ if include_paren {
2051
+ this. expected_tokens . push ( TokenType :: Token ( token:: OpenDelim ( token:: Paren ) ) ) ;
2052
+ }
2053
+ is_args_start ( & this. token , include_paren)
2053
2054
} ;
2054
2055
2055
- Ok ( if style == PathStyle :: Type && check_args_start ( self ) ||
2056
+ let expr_without_disambig = style == PathStyle :: Expr && check_args_start ( self , false ) ;
2057
+ let parser_snapshot_before_generics = self . clone ( ) ;
2058
+
2059
+ Ok ( if style == PathStyle :: Type && check_args_start ( self , true ) ||
2056
2060
style != PathStyle :: Mod && self . check ( & token:: ModSep )
2057
- && self . look_ahead ( 1 , |t| is_args_start ( t) ) {
2061
+ && self . look_ahead ( 1 , |t| is_args_start ( t, true ) )
2062
+ || expr_without_disambig {
2058
2063
// Generic arguments are found - `<`, `(`, `::<` or `::(`.
2059
2064
let lo = self . span ;
2060
2065
if self . eat ( & token:: ModSep ) && style == PathStyle :: Type && enable_warning {
@@ -2064,10 +2069,26 @@ impl<'a> Parser<'a> {
2064
2069
2065
2070
let args = if self . eat_lt ( ) {
2066
2071
// `<'a, T, A = U>`
2067
- let ( args, bindings) = self . parse_generic_args ( ) ?;
2068
- self . expect_gt ( ) ?;
2069
- let span = lo. to ( self . prev_span ) ;
2070
- AngleBracketedArgs { args, bindings, span } . into ( )
2072
+ let args: PResult < _ > = do catch {
2073
+ let ( args, bindings) = self . parse_generic_args ( ) ?;
2074
+ self . expect_gt ( ) ?;
2075
+ let span = lo. to ( self . prev_span ) ;
2076
+ AngleBracketedArgs { args, bindings, span }
2077
+ } ;
2078
+
2079
+ match args {
2080
+ Err ( mut err) => {
2081
+ if expr_without_disambig {
2082
+ err. cancel ( ) ;
2083
+ mem:: replace ( self , parser_snapshot_before_generics) ;
2084
+ return Ok ( PathSegment :: from_ident ( ident) ) ;
2085
+ }
2086
+ return Err ( err) ;
2087
+ }
2088
+ _ => {
2089
+ args?. into ( )
2090
+ }
2091
+ }
2071
2092
} else {
2072
2093
// `(T, U) -> R`
2073
2094
self . bump ( ) ; // `(`
0 commit comments