@@ -1790,6 +1790,35 @@ impl<'a> Parser<'a> {
1790
1790
self . look_ahead ( offset + 1 , |t| t == & token:: Colon )
1791
1791
}
1792
1792
1793
+ /// Skip unexpected attributes and doc comments in this position and emit an appropriate error.
1794
+ fn eat_incorrect_doc_comment ( & mut self , applied_to : & str ) {
1795
+ if let token:: DocComment ( _) = self . token {
1796
+ let mut err = self . diagnostic ( ) . struct_span_err (
1797
+ self . span ,
1798
+ & format ! ( "documentation comments cannot be applied to {}" , applied_to) ,
1799
+ ) ;
1800
+ err. span_label ( self . span , "doc comments are not allowed here" ) ;
1801
+ err. emit ( ) ;
1802
+ self . bump ( ) ;
1803
+ } else if self . token == token:: Pound && self . look_ahead ( 1 , |t| {
1804
+ * t == token:: OpenDelim ( token:: Bracket )
1805
+ } ) {
1806
+ let lo = self . span ;
1807
+ // Skip every token until next possible arg.
1808
+ while self . token != token:: CloseDelim ( token:: Bracket ) {
1809
+ self . bump ( ) ;
1810
+ }
1811
+ let sp = lo. to ( self . span ) ;
1812
+ self . bump ( ) ;
1813
+ let mut err = self . diagnostic ( ) . struct_span_err (
1814
+ sp,
1815
+ & format ! ( "attributes cannot be applied to {}" , applied_to) ,
1816
+ ) ;
1817
+ err. span_label ( sp, "attributes are not allowed here" ) ;
1818
+ err. emit ( ) ;
1819
+ }
1820
+ }
1821
+
1793
1822
/// This version of parse arg doesn't necessarily require
1794
1823
/// identifier names.
1795
1824
fn parse_arg_general ( & mut self , require_name : bool ) -> PResult < ' a , Arg > {
@@ -1798,7 +1827,8 @@ impl<'a> Parser<'a> {
1798
1827
let ( pat, ty) = if require_name || self . is_named_argument ( ) {
1799
1828
debug ! ( "parse_arg_general parse_pat (require_name:{})" ,
1800
1829
require_name) ;
1801
- let pat = self . parse_pat ( ) ?;
1830
+ self . eat_incorrect_doc_comment ( "method arguments" ) ;
1831
+ let pat = self . parse_pat ( Some ( "argument name" ) ) ?;
1802
1832
1803
1833
if let Err ( mut err) = self . expect ( & token:: Colon ) {
1804
1834
// If we find a pattern followed by an identifier, it could be an (incorrect)
@@ -1820,10 +1850,12 @@ impl<'a> Parser<'a> {
1820
1850
return Err ( err) ;
1821
1851
}
1822
1852
1853
+ self . eat_incorrect_doc_comment ( "a method argument's type" ) ;
1823
1854
( pat, self . parse_ty ( ) ?)
1824
1855
} else {
1825
1856
debug ! ( "parse_arg_general ident_to_pat" ) ;
1826
1857
let parser_snapshot_before_ty = self . clone ( ) ;
1858
+ self . eat_incorrect_doc_comment ( "a method argument's type" ) ;
1827
1859
let mut ty = self . parse_ty ( ) ;
1828
1860
if ty. is_ok ( ) && self . token == token:: Colon {
1829
1861
// This wasn't actually a type, but a pattern looking like a type,
@@ -1845,7 +1877,7 @@ impl<'a> Parser<'a> {
1845
1877
// Recover from attempting to parse the argument as a type without pattern.
1846
1878
err. cancel ( ) ;
1847
1879
mem:: replace ( self , parser_snapshot_before_ty) ;
1848
- let pat = self . parse_pat ( ) ?;
1880
+ let pat = self . parse_pat ( Some ( "argument name" ) ) ?;
1849
1881
self . expect ( & token:: Colon ) ?;
1850
1882
let ty = self . parse_ty ( ) ?;
1851
1883
@@ -1883,7 +1915,7 @@ impl<'a> Parser<'a> {
1883
1915
1884
1916
/// Parse an argument in a lambda header e.g. |arg, arg|
1885
1917
fn parse_fn_block_arg ( & mut self ) -> PResult < ' a , Arg > {
1886
- let pat = self . parse_pat ( ) ?;
1918
+ let pat = self . parse_pat ( Some ( "argument name" ) ) ?;
1887
1919
let t = if self . eat ( & token:: Colon ) {
1888
1920
self . parse_ty ( ) ?
1889
1921
} else {
@@ -2440,7 +2472,11 @@ impl<'a> Parser<'a> {
2440
2472
return Ok ( self . mk_expr ( lo. to ( hi) , ex, attrs) ) ;
2441
2473
}
2442
2474
if self . eat_keyword ( keywords:: Match ) {
2443
- return self . parse_match_expr ( attrs) ;
2475
+ let match_sp = self . prev_span ;
2476
+ return self . parse_match_expr ( attrs) . map_err ( |mut err| {
2477
+ err. span_label ( match_sp, "while parsing this match expression" ) ;
2478
+ err
2479
+ } ) ;
2444
2480
}
2445
2481
if self . eat_keyword ( keywords:: Unsafe ) {
2446
2482
return self . parse_block_expr (
@@ -3746,7 +3782,7 @@ impl<'a> Parser<'a> {
3746
3782
"`..` can only be used once per tuple or tuple struct pattern" ) ;
3747
3783
}
3748
3784
} else if !self . check ( & token:: CloseDelim ( token:: Paren ) ) {
3749
- fields. push ( self . parse_pat ( ) ?) ;
3785
+ fields. push ( self . parse_pat ( None ) ?) ;
3750
3786
} else {
3751
3787
break
3752
3788
}
@@ -3802,7 +3838,7 @@ impl<'a> Parser<'a> {
3802
3838
}
3803
3839
}
3804
3840
3805
- let subpat = self . parse_pat ( ) ?;
3841
+ let subpat = self . parse_pat ( None ) ?;
3806
3842
if before_slice && self . eat ( & token:: DotDot ) {
3807
3843
slice = Some ( subpat) ;
3808
3844
before_slice = false ;
@@ -3827,7 +3863,7 @@ impl<'a> Parser<'a> {
3827
3863
// Parsing a pattern of the form "fieldname: pat"
3828
3864
let fieldname = self . parse_field_name ( ) ?;
3829
3865
self . bump ( ) ;
3830
- let pat = self . parse_pat ( ) ?;
3866
+ let pat = self . parse_pat ( None ) ?;
3831
3867
hi = pat. span ;
3832
3868
( pat, fieldname, false )
3833
3869
} else {
@@ -4029,7 +4065,7 @@ impl<'a> Parser<'a> {
4029
4065
/// "top-level" patterns in a match arm, `for` loop, `let`, &c. (in contrast
4030
4066
/// to subpatterns within such).
4031
4067
fn parse_top_level_pat ( & mut self ) -> PResult < ' a , P < Pat > > {
4032
- let pat = self . parse_pat ( ) ?;
4068
+ let pat = self . parse_pat ( None ) ?;
4033
4069
if self . token == token:: Comma {
4034
4070
// An unexpected comma after a top-level pattern is a clue that the
4035
4071
// user (perhaps more accustomed to some other language) forgot the
@@ -4061,13 +4097,17 @@ impl<'a> Parser<'a> {
4061
4097
}
4062
4098
4063
4099
/// Parse a pattern.
4064
- pub fn parse_pat ( & mut self ) -> PResult < ' a , P < Pat > > {
4065
- self . parse_pat_with_range_pat ( true )
4100
+ pub fn parse_pat ( & mut self , expected : Option < & ' static str > ) -> PResult < ' a , P < Pat > > {
4101
+ self . parse_pat_with_range_pat ( true , expected )
4066
4102
}
4067
4103
4068
4104
/// Parse a pattern, with a setting whether modern range patterns e.g. `a..=b`, `a..b` are
4069
4105
/// allowed.
4070
- fn parse_pat_with_range_pat ( & mut self , allow_range_pat : bool ) -> PResult < ' a , P < Pat > > {
4106
+ fn parse_pat_with_range_pat (
4107
+ & mut self ,
4108
+ allow_range_pat : bool ,
4109
+ expected : Option < & ' static str > ,
4110
+ ) -> PResult < ' a , P < Pat > > {
4071
4111
maybe_whole ! ( self , NtPat , |x| x) ;
4072
4112
4073
4113
let lo = self . span ;
@@ -4083,7 +4123,7 @@ impl<'a> Parser<'a> {
4083
4123
err. span_label ( self . span , "unexpected lifetime" ) ;
4084
4124
return Err ( err) ;
4085
4125
}
4086
- let subpat = self . parse_pat_with_range_pat ( false ) ?;
4126
+ let subpat = self . parse_pat_with_range_pat ( false , expected ) ?;
4087
4127
pat = PatKind :: Ref ( subpat, mutbl) ;
4088
4128
}
4089
4129
token:: OpenDelim ( token:: Paren ) => {
@@ -4129,7 +4169,7 @@ impl<'a> Parser<'a> {
4129
4169
pat = self . parse_pat_ident ( BindingMode :: ByRef ( mutbl) ) ?;
4130
4170
} else if self . eat_keyword ( keywords:: Box ) {
4131
4171
// Parse box pat
4132
- let subpat = self . parse_pat_with_range_pat ( false ) ?;
4172
+ let subpat = self . parse_pat_with_range_pat ( false , None ) ?;
4133
4173
pat = PatKind :: Box ( subpat) ;
4134
4174
} else if self . token . is_ident ( ) && !self . token . is_reserved_ident ( ) &&
4135
4175
self . parse_as_ident ( ) {
@@ -4229,9 +4269,14 @@ impl<'a> Parser<'a> {
4229
4269
}
4230
4270
Err ( mut err) => {
4231
4271
self . cancel ( & mut err) ;
4232
- let msg = format ! ( "expected pattern, found {}" , self . this_token_descr( ) ) ;
4272
+ let expected = expected. unwrap_or ( "pattern" ) ;
4273
+ let msg = format ! (
4274
+ "expected {}, found {}" ,
4275
+ expected,
4276
+ self . this_token_descr( ) ,
4277
+ ) ;
4233
4278
let mut err = self . fatal ( & msg) ;
4234
- err. span_label ( self . span , "expected pattern" ) ;
4279
+ err. span_label ( self . span , format ! ( "expected {}" , expected ) ) ;
4235
4280
return Err ( err) ;
4236
4281
}
4237
4282
}
@@ -4275,7 +4320,7 @@ impl<'a> Parser<'a> {
4275
4320
-> PResult < ' a , PatKind > {
4276
4321
let ident = self . parse_ident ( ) ?;
4277
4322
let sub = if self . eat ( & token:: At ) {
4278
- Some ( self . parse_pat ( ) ?)
4323
+ Some ( self . parse_pat ( Some ( "binding pattern" ) ) ?)
4279
4324
} else {
4280
4325
None
4281
4326
} ;
0 commit comments