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