@@ -2355,6 +2355,55 @@ impl<'a> Parser<'a> {
23552355 )
23562356 }
23572357
2358+ // Assuming we have just parsed `.foo` (i.e., a dot and an ident), continue
2359+ // parsing into an expression.
2360+ fn parse_dot_suffix ( & mut self , ident : Ident , ident_span : Span , self_value : P < Expr > ) -> PResult < ' a , P < Expr > > {
2361+ let ( _, tys, bindings) = if self . eat ( & token:: ModSep ) {
2362+ try!( self . expect_lt ( ) ) ;
2363+ try!( self . parse_generic_values_after_lt ( ) )
2364+ } else {
2365+ ( Vec :: new ( ) , Vec :: new ( ) , Vec :: new ( ) )
2366+ } ;
2367+
2368+ if !bindings. is_empty ( ) {
2369+ let last_span = self . last_span ;
2370+ self . span_err ( last_span, "type bindings are only permitted on trait paths" ) ;
2371+ }
2372+
2373+ let lo = self_value. span . lo ;
2374+
2375+ Ok ( match self . token {
2376+ // expr.f() method call.
2377+ token:: OpenDelim ( token:: Paren ) => {
2378+ let mut es = try!( self . parse_unspanned_seq (
2379+ & token:: OpenDelim ( token:: Paren ) ,
2380+ & token:: CloseDelim ( token:: Paren ) ,
2381+ seq_sep_trailing_allowed ( token:: Comma ) ,
2382+ |p| Ok ( try!( p. parse_expr ( ) ) )
2383+ ) ) ;
2384+ let hi = self . last_span . hi ;
2385+
2386+ es. insert ( 0 , self_value) ;
2387+ let id = spanned ( ident_span. lo , ident_span. hi , ident) ;
2388+ let nd = self . mk_method_call ( id, tys, es) ;
2389+ self . mk_expr ( lo, hi, nd, None )
2390+ }
2391+ // Field access.
2392+ _ => {
2393+ if !tys. is_empty ( ) {
2394+ let last_span = self . last_span ;
2395+ self . span_err ( last_span,
2396+ "field expressions may not \
2397+ have type parameters") ;
2398+ }
2399+
2400+ let id = spanned ( ident_span. lo , ident_span. hi , ident) ;
2401+ let field = self . mk_field ( self_value, id) ;
2402+ self . mk_expr ( lo, ident_span. hi , field, None )
2403+ }
2404+ } )
2405+ }
2406+
23582407 fn parse_dot_or_call_expr_with_ ( & mut self , e0 : P < Expr > ) -> PResult < ' a , P < Expr > > {
23592408 let mut e = e0;
23602409 let lo = e. span . lo ;
@@ -2364,50 +2413,11 @@ impl<'a> Parser<'a> {
23642413 if self . eat ( & token:: Dot ) {
23652414 match self . token {
23662415 token:: Ident ( i, _) => {
2367- let dot = self . last_span . hi ;
2416+ let dot_pos = self . last_span . hi ;
23682417 hi = self . span . hi ;
23692418 self . bump ( ) ;
2370- let ( _, tys, bindings) = if self . eat ( & token:: ModSep ) {
2371- try!( self . expect_lt ( ) ) ;
2372- try!( self . parse_generic_values_after_lt ( ) )
2373- } else {
2374- ( Vec :: new ( ) , Vec :: new ( ) , Vec :: new ( ) )
2375- } ;
2376-
2377- if !bindings. is_empty ( ) {
2378- let last_span = self . last_span ;
2379- self . span_err ( last_span, "type bindings are only permitted on trait paths" ) ;
2380- }
23812419
2382- // expr.f() method call
2383- match self . token {
2384- token:: OpenDelim ( token:: Paren ) => {
2385- let mut es = try!( self . parse_unspanned_seq (
2386- & token:: OpenDelim ( token:: Paren ) ,
2387- & token:: CloseDelim ( token:: Paren ) ,
2388- seq_sep_trailing_allowed ( token:: Comma ) ,
2389- |p| Ok ( try!( p. parse_expr ( ) ) )
2390- ) ) ;
2391- hi = self . last_span . hi ;
2392-
2393- es. insert ( 0 , e) ;
2394- let id = spanned ( dot, hi, i) ;
2395- let nd = self . mk_method_call ( id, tys, es) ;
2396- e = self . mk_expr ( lo, hi, nd, None ) ;
2397- }
2398- _ => {
2399- if !tys. is_empty ( ) {
2400- let last_span = self . last_span ;
2401- self . span_err ( last_span,
2402- "field expressions may not \
2403- have type parameters") ;
2404- }
2405-
2406- let id = spanned ( dot, hi, i) ;
2407- let field = self . mk_field ( e, id) ;
2408- e = self . mk_expr ( lo, hi, field, None ) ;
2409- }
2410- }
2420+ e = try!( self . parse_dot_suffix ( i, mk_sp ( dot_pos, hi) , e) ) ;
24112421 }
24122422 token:: Literal ( token:: Integer ( n) , suf) => {
24132423 let sp = self . span ;
@@ -2452,7 +2462,17 @@ impl<'a> Parser<'a> {
24522462 self . abort_if_errors ( ) ;
24532463
24542464 }
2455- _ => return self . unexpected ( )
2465+ _ => {
2466+ // TODO special case lifetime
2467+ // FIXME Could factor this out into non_fatal_unexpected or something.
2468+ let actual = self . this_token_to_string ( ) ;
2469+ self . span_err ( self . span , & format ! ( "unexpected token: `{}`" , actual) ) ;
2470+
2471+ let dot_pos = self . last_span . hi ;
2472+ e = try!( self . parse_dot_suffix ( special_idents:: invalid,
2473+ mk_sp ( dot_pos, dot_pos) ,
2474+ e) ) ;
2475+ }
24562476 }
24572477 continue ;
24582478 }
0 commit comments