@@ -2355,6 +2355,55 @@ impl<'a> Parser<'a> {
2355
2355
)
2356
2356
}
2357
2357
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
+
2358
2407
fn parse_dot_or_call_expr_with_ ( & mut self , e0 : P < Expr > ) -> PResult < ' a , P < Expr > > {
2359
2408
let mut e = e0;
2360
2409
let lo = e. span . lo ;
@@ -2364,50 +2413,11 @@ impl<'a> Parser<'a> {
2364
2413
if self . eat ( & token:: Dot ) {
2365
2414
match self . token {
2366
2415
token:: Ident ( i, _) => {
2367
- let dot = self . last_span . hi ;
2416
+ let dot_pos = self . last_span . hi ;
2368
2417
hi = self . span . hi ;
2369
2418
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
- }
2381
2419
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) ) ;
2411
2421
}
2412
2422
token:: Literal ( token:: Integer ( n) , suf) => {
2413
2423
let sp = self . span ;
@@ -2452,7 +2462,17 @@ impl<'a> Parser<'a> {
2452
2462
self . abort_if_errors ( ) ;
2453
2463
2454
2464
}
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
+ }
2456
2476
}
2457
2477
continue ;
2458
2478
}
0 commit comments