@@ -652,9 +652,11 @@ impl<'a> Parser<'a> {
652652 } else {
653653 let token_str = Parser :: token_to_string ( t) ;
654654 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)
658660 }
659661 } else {
660662 self . expect_one_of ( unsafe { slice:: from_raw_parts ( t, 1 ) } , & [ ] )
@@ -1172,7 +1174,7 @@ impl<'a> Parser<'a> {
11721174 sep : SeqSep ,
11731175 f : F )
11741176 -> PResult < ' a , Vec < T > > where
1175- F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
1177+ F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
11761178 {
11771179 self . expect ( bra) ?;
11781180 let result = self . parse_seq_to_before_end ( ket, sep, f) ?;
@@ -1190,7 +1192,7 @@ impl<'a> Parser<'a> {
11901192 sep : SeqSep ,
11911193 f : F )
11921194 -> PResult < ' a , Spanned < Vec < T > > > where
1193- F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
1195+ F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
11941196 {
11951197 let lo = self . span ;
11961198 self . expect ( bra) ?;
@@ -1485,7 +1487,10 @@ impl<'a> Parser<'a> {
14851487 }
14861488 _ => {
14871489 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) ;
14891494 }
14901495 } ;
14911496 ( ident, ast:: TraitItemKind :: Method ( sig, body) , generics)
@@ -2216,7 +2221,12 @@ impl<'a> Parser<'a> {
22162221 TokenTree :: Delimited ( _, delimited) => Ok ( ( delim, delimited. stream ( ) . into ( ) ) ) ,
22172222 _ => unreachable ! ( ) ,
22182223 } ,
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+ }
22202230 }
22212231 }
22222232
@@ -2349,7 +2359,10 @@ impl<'a> Parser<'a> {
23492359 if self . eat_keyword ( keywords:: Loop ) {
23502360 return self . parse_loop_expr ( Some ( label) , lo, attrs)
23512361 }
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) ;
23532366 }
23542367 if self . eat_keyword ( keywords:: Loop ) {
23552368 let lo = self . prev_span ;
@@ -2408,6 +2421,7 @@ impl<'a> Parser<'a> {
24082421 // Catch this syntax error here, instead of in `parse_ident`, so
24092422 // that we can explicitly mention that let is not to be used as an expression
24102423 let mut db = self . fatal ( "expected expression, found statement (`let`)" ) ;
2424+ db. span_label ( self . span , "expected expression" ) ;
24112425 db. note ( "variable declaration using `let` is a statement" ) ;
24122426 return Err ( db) ;
24132427 } else if self . token . is_path_start ( ) {
@@ -2443,7 +2457,9 @@ impl<'a> Parser<'a> {
24432457 self . cancel ( & mut err) ;
24442458 let msg = format ! ( "expected expression, found {}" ,
24452459 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) ;
24472463 }
24482464 }
24492465 }
@@ -2733,7 +2749,9 @@ impl<'a> Parser<'a> {
27332749 self . look_ahead ( 1 , |t| t. is_ident ( ) ) => {
27342750 self . bump ( ) ;
27352751 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 ( ) ;
27372755 return
27382756 }
27392757 token:: Interpolated ( ref nt) => {
@@ -3212,7 +3230,13 @@ impl<'a> Parser<'a> {
32123230 err. span_label ( sp, "expected if condition here" ) ;
32133231 return Err ( err)
32143232 }
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+ } ) ?;
32163240 let mut els: Option < P < Expr > > = None ;
32173241 let mut hi = thn. span ;
32183242 if self . eat_keyword ( keywords:: Else ) {
@@ -3404,14 +3428,52 @@ impl<'a> Parser<'a> {
34043428 } else {
34053429 None
34063430 } ;
3431+ let arrow_span = self . span ;
34073432 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+ } ) ?;
34093440
34103441 let require_comma = classify:: expr_requires_semi_to_be_stmt ( & expr)
34113442 && self . token != token:: CloseDelim ( token:: Brace ) ;
34123443
34133444 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+ } ) ?;
34153477 } else {
34163478 self . eat ( & token:: Comma ) ;
34173479 }
@@ -3609,8 +3671,9 @@ impl<'a> Parser<'a> {
36093671 self . bump ( ) ;
36103672 if self . token != token:: CloseDelim ( token:: Brace ) {
36113673 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) ;
36143677 }
36153678 etc = true ;
36163679 break ;
@@ -3721,7 +3784,10 @@ impl<'a> Parser<'a> {
37213784 self . expect_and ( ) ?;
37223785 let mutbl = self . parse_mutability ( ) ;
37233786 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) ;
37253791 }
37263792 let subpat = self . parse_pat ( ) ?;
37273793 pat = PatKind :: Ref ( subpat, mutbl) ;
@@ -3806,7 +3872,10 @@ impl<'a> Parser<'a> {
38063872 }
38073873 token:: OpenDelim ( token:: Brace ) => {
38083874 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) ;
38103879 }
38113880 // Parse struct pattern
38123881 self . bump ( ) ;
@@ -3820,7 +3889,10 @@ impl<'a> Parser<'a> {
38203889 }
38213890 token:: OpenDelim ( token:: Paren ) => {
38223891 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) ;
38243896 }
38253897 // Parse tuple struct or enum pattern
38263898 let ( fields, ddpos, _) = self . parse_parenthesized_pat_list ( ) ?;
@@ -3850,7 +3922,9 @@ impl<'a> Parser<'a> {
38503922 Err ( mut err) => {
38513923 self . cancel ( & mut err) ;
38523924 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) ;
38543928 }
38553929 }
38563930 }
@@ -4250,9 +4324,11 @@ impl<'a> Parser<'a> {
42504324 ""
42514325 } ;
42524326 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)
42564332 } ,
42574333 } ;
42584334
@@ -5559,8 +5635,12 @@ impl<'a> Parser<'a> {
55595635 body
55605636 } else {
55615637 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) ;
55645644 } ;
55655645
55665646 Ok ( ( class_name, ItemKind :: Struct ( vdata, generics) , None ) )
@@ -5579,8 +5659,10 @@ impl<'a> Parser<'a> {
55795659 VariantData :: Struct ( self . parse_record_struct_body ( ) ?, ast:: DUMMY_NODE_ID )
55805660 } else {
55815661 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) ;
55845666 } ;
55855667
55865668 Ok ( ( class_name, ItemKind :: Union ( vdata, generics) , None ) )
@@ -5627,9 +5709,10 @@ impl<'a> Parser<'a> {
56275709 self . eat ( & token:: CloseDelim ( token:: Brace ) ) ;
56285710 } else {
56295711 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) ;
56335716 }
56345717
56355718 Ok ( fields)
@@ -5802,9 +5885,11 @@ impl<'a> Parser<'a> {
58025885 if !self . eat ( term) {
58035886 let token_str = self . this_token_to_string ( ) ;
58045887 let mut err = self . fatal ( & format ! ( "expected item, found `{}`" , token_str) ) ;
5805- let msg = "consider removing this semicolon" ;
58065888 if token_str == ";" {
5889+ let msg = "consider removing this semicolon" ;
58075890 err. span_suggestion_short ( self . span , msg, "" . to_string ( ) ) ;
5891+ } else {
5892+ err. span_label ( self . span , "expected item" ) ;
58085893 }
58095894 return Err ( err) ;
58105895 }
@@ -6961,7 +7046,12 @@ impl<'a> Parser<'a> {
69617046 self . expect_no_suffix ( sp, "string literal" , suf) ;
69627047 Ok ( ( s, style) )
69637048 }
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+ }
69657055 }
69667056 }
69677057}
0 commit comments