@@ -974,11 +974,12 @@ impl<'a> Parser<'a> {
974
974
pub fn eat_to_tokens ( & mut self , kets : & [ & token:: Token ] ) {
975
975
let handler = self . diagnostic ( ) ;
976
976
977
- self . parse_seq_to_before_tokens ( kets,
978
- SeqSep :: none ( ) ,
979
- TokenExpectType :: Expect ,
980
- |p| Ok ( p. parse_token_tree ( ) ) ,
981
- |mut e| handler. cancel ( & mut e) ) ;
977
+ if let Err ( ref mut err) = self . parse_seq_to_before_tokens ( kets,
978
+ SeqSep :: none ( ) ,
979
+ TokenExpectType :: Expect ,
980
+ |p| Ok ( p. parse_token_tree ( ) ) ) {
981
+ handler. cancel ( err) ;
982
+ }
982
983
}
983
984
984
985
/// Parse a sequence, including the closing delimiter. The function
@@ -991,7 +992,7 @@ impl<'a> Parser<'a> {
991
992
-> PResult < ' a , Vec < T > > where
992
993
F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
993
994
{
994
- let val = self . parse_seq_to_before_end ( ket, sep, f) ;
995
+ let val = self . parse_seq_to_before_end ( ket, sep, f) ? ;
995
996
self . bump ( ) ;
996
997
Ok ( val)
997
998
}
@@ -1003,22 +1004,19 @@ impl<'a> Parser<'a> {
1003
1004
ket : & token:: Token ,
1004
1005
sep : SeqSep ,
1005
1006
f : F )
1006
- -> Vec < T >
1007
- where F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T >
1007
+ -> PResult < ' a , Vec < T > >
1008
+ where F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T >
1008
1009
{
1009
- self . parse_seq_to_before_tokens ( & [ ket] , sep, TokenExpectType :: Expect , f, | mut e| e . emit ( ) )
1010
+ self . parse_seq_to_before_tokens ( & [ ket] , sep, TokenExpectType :: Expect , f)
1010
1011
}
1011
1012
1012
- // `fe` is an error handler.
1013
- fn parse_seq_to_before_tokens < T , F , Fe > ( & mut self ,
1013
+ fn parse_seq_to_before_tokens < T , F > ( & mut self ,
1014
1014
kets : & [ & token:: Token ] ,
1015
1015
sep : SeqSep ,
1016
1016
expect : TokenExpectType ,
1017
- mut f : F ,
1018
- mut fe : Fe )
1019
- -> Vec < T >
1020
- where F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
1021
- Fe : FnMut ( DiagnosticBuilder )
1017
+ mut f : F )
1018
+ -> PResult < ' a , Vec < T > >
1019
+ where F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T >
1022
1020
{
1023
1021
let mut first: bool = true ;
1024
1022
let mut v = vec ! [ ] ;
@@ -1031,14 +1029,14 @@ impl<'a> Parser<'a> {
1031
1029
if first {
1032
1030
first = false ;
1033
1031
} else {
1034
- if let Err ( e) = self . expect ( t) {
1035
- fe ( e) ;
1032
+ if let Err ( mut e) = self . expect ( t) {
1036
1033
// Attempt to keep parsing if it was a similar separator
1037
1034
if let Some ( ref tokens) = t. similar_tokens ( ) {
1038
1035
if tokens. contains ( & self . token ) {
1039
1036
self . bump ( ) ;
1040
1037
}
1041
1038
}
1039
+ e. emit ( ) ;
1042
1040
// Attempt to keep parsing if it was an omitted separator
1043
1041
match f ( self ) {
1044
1042
Ok ( t) => {
@@ -1062,16 +1060,11 @@ impl<'a> Parser<'a> {
1062
1060
break ;
1063
1061
}
1064
1062
1065
- match f ( self ) {
1066
- Ok ( t) => v. push ( t) ,
1067
- Err ( e) => {
1068
- fe ( e) ;
1069
- break ;
1070
- }
1071
- }
1063
+ let t = f ( self ) ?;
1064
+ v. push ( t) ;
1072
1065
}
1073
1066
1074
- v
1067
+ Ok ( v )
1075
1068
}
1076
1069
1077
1070
/// Parse a sequence, including the closing delimiter. The function
@@ -1086,7 +1079,7 @@ impl<'a> Parser<'a> {
1086
1079
F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , T > ,
1087
1080
{
1088
1081
self . expect ( bra) ?;
1089
- let result = self . parse_seq_to_before_end ( ket, sep, f) ;
1082
+ let result = self . parse_seq_to_before_end ( ket, sep, f) ? ;
1090
1083
if self . token == * ket {
1091
1084
self . bump ( ) ;
1092
1085
}
@@ -1105,7 +1098,7 @@ impl<'a> Parser<'a> {
1105
1098
{
1106
1099
let lo = self . span ;
1107
1100
self . expect ( bra) ?;
1108
- let result = self . parse_seq_to_before_end ( ket, sep, f) ;
1101
+ let result = self . parse_seq_to_before_end ( ket, sep, f) ? ;
1109
1102
let hi = self . span ;
1110
1103
self . bump ( ) ;
1111
1104
Ok ( respan ( lo. to ( hi) , result) )
@@ -1551,7 +1544,7 @@ impl<'a> Parser<'a> {
1551
1544
} ;
1552
1545
1553
1546
let span = lo. to ( self . prev_span ) ;
1554
- let ty = Ty { node : node , span : span, id : ast:: DUMMY_NODE_ID } ;
1547
+ let ty = Ty { node, span, id : ast:: DUMMY_NODE_ID } ;
1555
1548
1556
1549
// Try to recover from use of `+` with incorrect priority.
1557
1550
self . maybe_recover_from_bad_type_plus ( allow_plus, & ty) ?;
@@ -1868,8 +1861,11 @@ impl<'a> Parser<'a> {
1868
1861
self . parse_path ( style)
1869
1862
}
1870
1863
1871
- fn parse_path_segments ( & mut self , segments : & mut Vec < PathSegment > , style : PathStyle ,
1872
- enable_warning : bool ) -> PResult < ' a , ( ) > {
1864
+ fn parse_path_segments ( & mut self ,
1865
+ segments : & mut Vec < PathSegment > ,
1866
+ style : PathStyle ,
1867
+ enable_warning : bool )
1868
+ -> PResult < ' a , ( ) > {
1873
1869
loop {
1874
1870
segments. push ( self . parse_path_segment ( style, enable_warning) ?) ;
1875
1871
@@ -1914,9 +1910,12 @@ impl<'a> Parser<'a> {
1914
1910
} else {
1915
1911
// `(T, U) -> R`
1916
1912
self . bump ( ) ; // `(`
1917
- let inputs = self . parse_seq_to_end ( & token:: CloseDelim ( token:: Paren ) ,
1918
- SeqSep :: trailing_allowed ( token:: Comma ) ,
1919
- |p| p. parse_ty ( ) ) ?;
1913
+ let inputs = self . parse_seq_to_before_tokens (
1914
+ & [ & token:: CloseDelim ( token:: Paren ) ] ,
1915
+ SeqSep :: trailing_allowed ( token:: Comma ) ,
1916
+ TokenExpectType :: Expect ,
1917
+ |p| p. parse_ty ( ) ) ?;
1918
+ self . bump ( ) ; // `)`
1920
1919
let output = if self . eat ( & token:: RArrow ) {
1921
1920
Some ( self . parse_ty_no_plus ( ) ?)
1922
1921
} else {
@@ -3315,10 +3314,12 @@ impl<'a> Parser<'a> {
3315
3314
}
3316
3315
3317
3316
/// Parse the RHS of a local variable declaration (e.g. '= 14;')
3318
- fn parse_initializer ( & mut self ) -> PResult < ' a , Option < P < Expr > > > {
3317
+ fn parse_initializer ( & mut self , skip_eq : bool ) -> PResult < ' a , Option < P < Expr > > > {
3319
3318
if self . check ( & token:: Eq ) {
3320
3319
self . bump ( ) ;
3321
3320
Ok ( Some ( self . parse_expr ( ) ?) )
3321
+ } else if skip_eq {
3322
+ Ok ( Some ( self . parse_expr ( ) ?) )
3322
3323
} else {
3323
3324
Ok ( None )
3324
3325
}
@@ -3725,12 +3726,56 @@ impl<'a> Parser<'a> {
3725
3726
let lo = self . prev_span ;
3726
3727
let pat = self . parse_pat ( ) ?;
3727
3728
3728
- let ty = if self . eat ( & token:: Colon ) {
3729
- Some ( self . parse_ty ( ) ?)
3729
+ let ( err, ty) = if self . eat ( & token:: Colon ) {
3730
+ // Save the state of the parser before parsing type normally, in case there is a `:`
3731
+ // instead of an `=` typo.
3732
+ let parser_snapshot_before_type = self . clone ( ) ;
3733
+ let colon_sp = self . prev_span ;
3734
+ match self . parse_ty ( ) {
3735
+ Ok ( ty) => ( None , Some ( ty) ) ,
3736
+ Err ( mut err) => {
3737
+ // Rewind to before attempting to parse the type and continue parsing
3738
+ let parser_snapshot_after_type = self . clone ( ) ;
3739
+ mem:: replace ( self , parser_snapshot_before_type) ;
3740
+
3741
+ let snippet = self . sess . codemap ( ) . span_to_snippet ( pat. span ) . unwrap ( ) ;
3742
+ err. span_label ( pat. span , format ! ( "while parsing the type for `{}`" , snippet) ) ;
3743
+ ( Some ( ( parser_snapshot_after_type, colon_sp, err) ) , None )
3744
+ }
3745
+ }
3730
3746
} else {
3731
- None
3747
+ ( None , None )
3748
+ } ;
3749
+ let init = match ( self . parse_initializer ( err. is_some ( ) ) , err) {
3750
+ ( Ok ( init) , None ) => { // init parsed, ty parsed
3751
+ init
3752
+ }
3753
+ ( Ok ( init) , Some ( ( _, colon_sp, mut err) ) ) => { // init parsed, ty error
3754
+ // Could parse the type as if it were the initializer, it is likely there was a
3755
+ // typo in the code: `:` instead of `=`. Add suggestion and emit the error.
3756
+ err. span_suggestion_short ( colon_sp,
3757
+ "use `=` if you meant to assign" ,
3758
+ "=" . to_string ( ) ) ;
3759
+ err. emit ( ) ;
3760
+ // As this was parsed successfuly, continue as if the code has been fixed for the
3761
+ // rest of the file. It will still fail due to the emitted error, but we avoid
3762
+ // extra noise.
3763
+ init
3764
+ }
3765
+ ( Err ( mut init_err) , Some ( ( snapshot, _, ty_err) ) ) => { // init error, ty error
3766
+ init_err. cancel ( ) ;
3767
+ // Couldn't parse the type nor the initializer, only raise the type error and
3768
+ // return to the parser state before parsing the type as the initializer.
3769
+ // let x: <parse_error>;
3770
+ mem:: replace ( self , snapshot) ;
3771
+ return Err ( ty_err) ;
3772
+ }
3773
+ ( Err ( err) , None ) => { // init error, ty parsed
3774
+ // Couldn't parse the initializer and we're not attempting to recover a failed
3775
+ // parse of the type, return the error.
3776
+ return Err ( err) ;
3777
+ }
3732
3778
} ;
3733
- let init = self . parse_initializer ( ) ?;
3734
3779
let hi = if self . token == token:: Semi {
3735
3780
self . span
3736
3781
} else {
@@ -4797,14 +4842,14 @@ impl<'a> Parser<'a> {
4797
4842
} else if self . eat ( & token:: Comma ) {
4798
4843
let mut fn_inputs = vec ! [ self_arg] ;
4799
4844
fn_inputs. append ( & mut self . parse_seq_to_before_end (
4800
- & token:: CloseDelim ( token:: Paren ) , sep, parse_arg_fn)
4845
+ & token:: CloseDelim ( token:: Paren ) , sep, parse_arg_fn) ?
4801
4846
) ;
4802
4847
fn_inputs
4803
4848
} else {
4804
4849
return self . unexpected ( ) ;
4805
4850
}
4806
4851
} else {
4807
- self . parse_seq_to_before_end ( & token:: CloseDelim ( token:: Paren ) , sep, parse_arg_fn)
4852
+ self . parse_seq_to_before_end ( & token:: CloseDelim ( token:: Paren ) , sep, parse_arg_fn) ?
4808
4853
} ;
4809
4854
4810
4855
// Parse closing paren and return type.
@@ -4827,9 +4872,8 @@ impl<'a> Parser<'a> {
4827
4872
& [ & token:: BinOp ( token:: Or ) , & token:: OrOr ] ,
4828
4873
SeqSep :: trailing_allowed ( token:: Comma ) ,
4829
4874
TokenExpectType :: NoExpect ,
4830
- |p| p. parse_fn_block_arg ( ) ,
4831
- |mut e| e. emit ( )
4832
- ) ;
4875
+ |p| p. parse_fn_block_arg ( )
4876
+ ) ?;
4833
4877
self . expect_or ( ) ?;
4834
4878
args
4835
4879
}
0 commit comments