@@ -652,9 +652,11 @@ impl<'a> Parser<'a> {
652
652
} else {
653
653
let token_str = Parser :: token_to_string ( t) ;
654
654
let this_token_str = self . this_token_to_string ( ) ;
655
- Err ( self . fatal ( & format ! ( "expected `{}`, found `{}`" ,
656
- token_str,
657
- this_token_str) ) )
655
+ let mut err = self . fatal ( & format ! ( "expected `{}`, found `{}`" ,
656
+ token_str,
657
+ this_token_str) ) ;
658
+ err. span_label ( self . span , format ! ( "expected `{}`" , token_str) ) ;
659
+ Err ( err)
658
660
}
659
661
} else {
660
662
self . expect_one_of ( unsafe { slice:: from_raw_parts ( t, 1 ) } , & [ ] )
@@ -1172,7 +1174,7 @@ impl<'a> Parser<'a> {
1172
1174
sep : SeqSep ,
1173
1175
f : F )
1174
1176
-> PResult < ' a , Vec < T > > where
1175
- F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
1177
+ F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
1176
1178
{
1177
1179
self . expect ( bra) ?;
1178
1180
let result = self . parse_seq_to_before_end ( ket, sep, f) ?;
@@ -1190,7 +1192,7 @@ impl<'a> Parser<'a> {
1190
1192
sep : SeqSep ,
1191
1193
f : F )
1192
1194
-> PResult < ' a , Spanned < Vec < T > > > where
1193
- F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
1195
+ F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
1194
1196
{
1195
1197
let lo = self . span ;
1196
1198
self . expect ( bra) ?;
@@ -1485,7 +1487,10 @@ impl<'a> Parser<'a> {
1485
1487
}
1486
1488
_ => {
1487
1489
let token_str = self . this_token_to_string ( ) ;
1488
- return Err ( self . fatal ( & format ! ( "expected `;` or `{{`, found `{}`" , token_str) ) ) ;
1490
+ let mut err = self . fatal ( & format ! ( "expected `;` or `{{`, found `{}`" ,
1491
+ token_str) ) ;
1492
+ err. span_label ( self . span , "expected `;` or `{`" ) ;
1493
+ return Err ( err) ;
1489
1494
}
1490
1495
} ;
1491
1496
( ident, ast:: TraitItemKind :: Method ( sig, body) , generics)
@@ -2216,7 +2221,12 @@ impl<'a> Parser<'a> {
2216
2221
TokenTree :: Delimited ( _, delimited) => Ok ( ( delim, delimited. stream ( ) . into ( ) ) ) ,
2217
2222
_ => unreachable ! ( ) ,
2218
2223
} ,
2219
- _ => Err ( self . fatal ( "expected open delimiter" ) ) ,
2224
+ _ => {
2225
+ let msg = "expected open delimiter" ;
2226
+ let mut err = self . fatal ( msg) ;
2227
+ err. span_label ( self . span , msg) ;
2228
+ Err ( err)
2229
+ }
2220
2230
}
2221
2231
}
2222
2232
@@ -2349,7 +2359,10 @@ impl<'a> Parser<'a> {
2349
2359
if self . eat_keyword ( keywords:: Loop ) {
2350
2360
return self . parse_loop_expr ( Some ( label) , lo, attrs)
2351
2361
}
2352
- return Err ( self . fatal ( "expected `while`, `for`, or `loop` after a label" ) )
2362
+ let msg = "expected `while`, `for`, or `loop` after a label" ;
2363
+ let mut err = self . fatal ( msg) ;
2364
+ err. span_label ( self . span , msg) ;
2365
+ return Err ( err) ;
2353
2366
}
2354
2367
if self . eat_keyword ( keywords:: Loop ) {
2355
2368
let lo = self . prev_span ;
@@ -2408,6 +2421,7 @@ impl<'a> Parser<'a> {
2408
2421
// Catch this syntax error here, instead of in `parse_ident`, so
2409
2422
// that we can explicitly mention that let is not to be used as an expression
2410
2423
let mut db = self . fatal ( "expected expression, found statement (`let`)" ) ;
2424
+ db. span_label ( self . span , "expected expression" ) ;
2411
2425
db. note ( "variable declaration using `let` is a statement" ) ;
2412
2426
return Err ( db) ;
2413
2427
} else if self . token . is_path_start ( ) {
@@ -2443,7 +2457,9 @@ impl<'a> Parser<'a> {
2443
2457
self . cancel ( & mut err) ;
2444
2458
let msg = format ! ( "expected expression, found {}" ,
2445
2459
self . this_token_descr( ) ) ;
2446
- return Err ( self . fatal ( & msg) ) ;
2460
+ let mut err = self . fatal ( & msg) ;
2461
+ err. span_label ( self . span , "expected expression" ) ;
2462
+ return Err ( err) ;
2447
2463
}
2448
2464
}
2449
2465
}
@@ -2733,7 +2749,9 @@ impl<'a> Parser<'a> {
2733
2749
self . look_ahead ( 1 , |t| t. is_ident ( ) ) => {
2734
2750
self . bump ( ) ;
2735
2751
let name = match self . token { token:: Ident ( ident) => ident, _ => unreachable ! ( ) } ;
2736
- self . fatal ( & format ! ( "unknown macro variable `{}`" , name) ) . emit ( ) ;
2752
+ let mut err = self . fatal ( & format ! ( "unknown macro variable `{}`" , name) ) ;
2753
+ err. span_label ( self . span , "unknown macro variable" ) ;
2754
+ err. emit ( ) ;
2737
2755
return
2738
2756
}
2739
2757
token:: Interpolated ( ref nt) => {
@@ -3212,7 +3230,13 @@ impl<'a> Parser<'a> {
3212
3230
err. span_label ( sp, "expected if condition here" ) ;
3213
3231
return Err ( err)
3214
3232
}
3215
- let thn = self . parse_block ( ) ?;
3233
+ let not_block = self . token != token:: OpenDelim ( token:: Brace ) ;
3234
+ let thn = self . parse_block ( ) . map_err ( |mut err| {
3235
+ if not_block {
3236
+ err. span_label ( lo, "this `if` statement has a condition, but no block" ) ;
3237
+ }
3238
+ err
3239
+ } ) ?;
3216
3240
let mut els: Option < P < Expr > > = None ;
3217
3241
let mut hi = thn. span ;
3218
3242
if self . eat_keyword ( keywords:: Else ) {
@@ -3404,14 +3428,52 @@ impl<'a> Parser<'a> {
3404
3428
} else {
3405
3429
None
3406
3430
} ;
3431
+ let arrow_span = self . span ;
3407
3432
self . expect ( & token:: FatArrow ) ?;
3408
- let expr = self . parse_expr_res ( Restrictions :: STMT_EXPR , None ) ?;
3433
+ let arm_start_span = self . span ;
3434
+
3435
+ let expr = self . parse_expr_res ( Restrictions :: STMT_EXPR , None )
3436
+ . map_err ( |mut err| {
3437
+ err. span_label ( arrow_span, "while parsing the `match` arm starting here" ) ;
3438
+ err
3439
+ } ) ?;
3409
3440
3410
3441
let require_comma = classify:: expr_requires_semi_to_be_stmt ( & expr)
3411
3442
&& self . token != token:: CloseDelim ( token:: Brace ) ;
3412
3443
3413
3444
if require_comma {
3414
- self . expect_one_of ( & [ token:: Comma ] , & [ token:: CloseDelim ( token:: Brace ) ] ) ?;
3445
+ let cm = self . sess . codemap ( ) ;
3446
+ self . expect_one_of ( & [ token:: Comma ] , & [ token:: CloseDelim ( token:: Brace ) ] )
3447
+ . map_err ( |mut err| {
3448
+ match ( cm. span_to_lines ( expr. span ) , cm. span_to_lines ( arm_start_span) ) {
3449
+ ( Ok ( ref expr_lines) , Ok ( ref arm_start_lines) )
3450
+ if arm_start_lines. lines [ 0 ] . end_col == expr_lines. lines [ 0 ] . end_col
3451
+ && expr_lines. lines . len ( ) == 2
3452
+ && self . token == token:: FatArrow => {
3453
+ // We check wether there's any trailing code in the parse span, if there
3454
+ // isn't, we very likely have the following:
3455
+ //
3456
+ // X | &Y => "y"
3457
+ // | -- - missing comma
3458
+ // | |
3459
+ // | arrow_span
3460
+ // X | &X => "x"
3461
+ // | - ^^ self.span
3462
+ // | |
3463
+ // | parsed until here as `"y" & X`
3464
+ err. span_suggestion_short (
3465
+ cm. next_point ( arm_start_span) ,
3466
+ "missing a comma here to end this `match` arm" ,
3467
+ "," . to_owned ( )
3468
+ ) ;
3469
+ }
3470
+ _ => {
3471
+ err. span_label ( arrow_span,
3472
+ "while parsing the `match` arm starting here" ) ;
3473
+ }
3474
+ }
3475
+ err
3476
+ } ) ?;
3415
3477
} else {
3416
3478
self . eat ( & token:: Comma ) ;
3417
3479
}
@@ -3609,8 +3671,9 @@ impl<'a> Parser<'a> {
3609
3671
self . bump ( ) ;
3610
3672
if self . token != token:: CloseDelim ( token:: Brace ) {
3611
3673
let token_str = self . this_token_to_string ( ) ;
3612
- return Err ( self . fatal ( & format ! ( "expected `{}`, found `{}`" , "}" ,
3613
- token_str) ) )
3674
+ let mut err = self . fatal ( & format ! ( "expected `{}`, found `{}`" , "}" , token_str) ) ;
3675
+ err. span_label ( self . span , "expected `}`" ) ;
3676
+ return Err ( err) ;
3614
3677
}
3615
3678
etc = true ;
3616
3679
break ;
@@ -3721,7 +3784,10 @@ impl<'a> Parser<'a> {
3721
3784
self . expect_and ( ) ?;
3722
3785
let mutbl = self . parse_mutability ( ) ;
3723
3786
if let token:: Lifetime ( ident) = self . token {
3724
- return Err ( self . fatal ( & format ! ( "unexpected lifetime `{}` in pattern" , ident) ) ) ;
3787
+ let mut err = self . fatal ( & format ! ( "unexpected lifetime `{}` in pattern" ,
3788
+ ident) ) ;
3789
+ err. span_label ( self . span , "unexpected lifetime" ) ;
3790
+ return Err ( err) ;
3725
3791
}
3726
3792
let subpat = self . parse_pat ( ) ?;
3727
3793
pat = PatKind :: Ref ( subpat, mutbl) ;
@@ -3806,7 +3872,10 @@ impl<'a> Parser<'a> {
3806
3872
}
3807
3873
token:: OpenDelim ( token:: Brace ) => {
3808
3874
if qself. is_some ( ) {
3809
- return Err ( self . fatal ( "unexpected `{` after qualified path" ) ) ;
3875
+ let msg = "unexpected `{` after qualified path" ;
3876
+ let mut err = self . fatal ( msg) ;
3877
+ err. span_label ( self . span , msg) ;
3878
+ return Err ( err) ;
3810
3879
}
3811
3880
// Parse struct pattern
3812
3881
self . bump ( ) ;
@@ -3820,7 +3889,10 @@ impl<'a> Parser<'a> {
3820
3889
}
3821
3890
token:: OpenDelim ( token:: Paren ) => {
3822
3891
if qself. is_some ( ) {
3823
- return Err ( self . fatal ( "unexpected `(` after qualified path" ) ) ;
3892
+ let msg = "unexpected `(` after qualified path" ;
3893
+ let mut err = self . fatal ( msg) ;
3894
+ err. span_label ( self . span , msg) ;
3895
+ return Err ( err) ;
3824
3896
}
3825
3897
// Parse tuple struct or enum pattern
3826
3898
let ( fields, ddpos, _) = self . parse_parenthesized_pat_list ( ) ?;
@@ -3850,7 +3922,9 @@ impl<'a> Parser<'a> {
3850
3922
Err ( mut err) => {
3851
3923
self . cancel ( & mut err) ;
3852
3924
let msg = format ! ( "expected pattern, found {}" , self . this_token_descr( ) ) ;
3853
- return Err ( self . fatal ( & msg) ) ;
3925
+ let mut err = self . fatal ( & msg) ;
3926
+ err. span_label ( self . span , "expected pattern" ) ;
3927
+ return Err ( err) ;
3854
3928
}
3855
3929
}
3856
3930
}
@@ -4250,9 +4324,11 @@ impl<'a> Parser<'a> {
4250
4324
""
4251
4325
} ;
4252
4326
let tok_str = self . this_token_to_string ( ) ;
4253
- return Err ( self . fatal ( & format ! ( "expected {}`(` or `{{`, found `{}`" ,
4254
- ident_str,
4255
- tok_str) ) )
4327
+ let mut err = self . fatal ( & format ! ( "expected {}`(` or `{{`, found `{}`" ,
4328
+ ident_str,
4329
+ tok_str) ) ;
4330
+ err. span_label ( self . span , format ! ( "expected {}`(` or `{{`" , ident_str) ) ;
4331
+ return Err ( err)
4256
4332
} ,
4257
4333
} ;
4258
4334
@@ -5559,8 +5635,12 @@ impl<'a> Parser<'a> {
5559
5635
body
5560
5636
} else {
5561
5637
let token_str = self . this_token_to_string ( ) ;
5562
- return Err ( self . fatal ( & format ! ( "expected `where`, `{{`, `(`, or `;` after struct \
5563
- name, found `{}`", token_str) ) )
5638
+ let mut err = self . fatal ( & format ! (
5639
+ "expected `where`, `{{`, `(`, or `;` after struct name, found `{}`" ,
5640
+ token_str
5641
+ ) ) ;
5642
+ err. span_label ( self . span , "expected `where`, `{`, `(`, or `;` after struct name" ) ;
5643
+ return Err ( err) ;
5564
5644
} ;
5565
5645
5566
5646
Ok ( ( class_name, ItemKind :: Struct ( vdata, generics) , None ) )
@@ -5579,8 +5659,10 @@ impl<'a> Parser<'a> {
5579
5659
VariantData :: Struct ( self . parse_record_struct_body ( ) ?, ast:: DUMMY_NODE_ID )
5580
5660
} else {
5581
5661
let token_str = self . this_token_to_string ( ) ;
5582
- return Err ( self . fatal ( & format ! ( "expected `where` or `{{` after union \
5583
- name, found `{}`", token_str) ) )
5662
+ let mut err = self . fatal ( & format ! (
5663
+ "expected `where` or `{{` after union name, found `{}`" , token_str) ) ;
5664
+ err. span_label ( self . span , "expected `where` or `{` after union name" ) ;
5665
+ return Err ( err) ;
5584
5666
} ;
5585
5667
5586
5668
Ok ( ( class_name, ItemKind :: Union ( vdata, generics) , None ) )
@@ -5627,9 +5709,10 @@ impl<'a> Parser<'a> {
5627
5709
self . eat ( & token:: CloseDelim ( token:: Brace ) ) ;
5628
5710
} else {
5629
5711
let token_str = self . this_token_to_string ( ) ;
5630
- return Err ( self . fatal ( & format ! ( "expected `where`, or `{{` after struct \
5631
- name, found `{}`",
5632
- token_str) ) ) ;
5712
+ let mut err = self . fatal ( & format ! (
5713
+ "expected `where`, or `{{` after struct name, found `{}`" , token_str) ) ;
5714
+ err. span_label ( self . span , "expected `where`, or `{` after struct name" ) ;
5715
+ return Err ( err) ;
5633
5716
}
5634
5717
5635
5718
Ok ( fields)
@@ -5802,9 +5885,11 @@ impl<'a> Parser<'a> {
5802
5885
if !self . eat ( term) {
5803
5886
let token_str = self . this_token_to_string ( ) ;
5804
5887
let mut err = self . fatal ( & format ! ( "expected item, found `{}`" , token_str) ) ;
5805
- let msg = "consider removing this semicolon" ;
5806
5888
if token_str == ";" {
5889
+ let msg = "consider removing this semicolon" ;
5807
5890
err. span_suggestion_short ( self . span , msg, "" . to_string ( ) ) ;
5891
+ } else {
5892
+ err. span_label ( self . span , "expected item" ) ;
5808
5893
}
5809
5894
return Err ( err) ;
5810
5895
}
@@ -6961,7 +7046,12 @@ impl<'a> Parser<'a> {
6961
7046
self . expect_no_suffix ( sp, "string literal" , suf) ;
6962
7047
Ok ( ( s, style) )
6963
7048
}
6964
- _ => Err ( self . fatal ( "expected string literal" ) )
7049
+ _ => {
7050
+ let msg = "expected string literal" ;
7051
+ let mut err = self . fatal ( msg) ;
7052
+ err. span_label ( self . span , msg) ;
7053
+ Err ( err)
7054
+ }
6965
7055
}
6966
7056
}
6967
7057
}
0 commit comments