@@ -1790,6 +1790,35 @@ impl<'a> Parser<'a> {
17901790 self . look_ahead ( offset + 1 , |t| t == & token:: Colon )
17911791 }
17921792
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+
17931822 /// This version of parse arg doesn't necessarily require
17941823 /// identifier names.
17951824 fn parse_arg_general ( & mut self , require_name : bool ) -> PResult < ' a , Arg > {
@@ -1798,7 +1827,8 @@ impl<'a> Parser<'a> {
17981827 let ( pat, ty) = if require_name || self . is_named_argument ( ) {
17991828 debug ! ( "parse_arg_general parse_pat (require_name:{})" ,
18001829 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" ) ) ?;
18021832
18031833 if let Err ( mut err) = self . expect ( & token:: Colon ) {
18041834 // If we find a pattern followed by an identifier, it could be an (incorrect)
@@ -1820,10 +1850,12 @@ impl<'a> Parser<'a> {
18201850 return Err ( err) ;
18211851 }
18221852
1853+ self . eat_incorrect_doc_comment ( "a method argument's type" ) ;
18231854 ( pat, self . parse_ty ( ) ?)
18241855 } else {
18251856 debug ! ( "parse_arg_general ident_to_pat" ) ;
18261857 let parser_snapshot_before_ty = self . clone ( ) ;
1858+ self . eat_incorrect_doc_comment ( "a method argument's type" ) ;
18271859 let mut ty = self . parse_ty ( ) ;
18281860 if ty. is_ok ( ) && self . token == token:: Colon {
18291861 // This wasn't actually a type, but a pattern looking like a type,
@@ -1845,7 +1877,7 @@ impl<'a> Parser<'a> {
18451877 // Recover from attempting to parse the argument as a type without pattern.
18461878 err. cancel ( ) ;
18471879 mem:: replace ( self , parser_snapshot_before_ty) ;
1848- let pat = self . parse_pat ( ) ?;
1880+ let pat = self . parse_pat ( Some ( "argument name" ) ) ?;
18491881 self . expect ( & token:: Colon ) ?;
18501882 let ty = self . parse_ty ( ) ?;
18511883
@@ -1883,7 +1915,7 @@ impl<'a> Parser<'a> {
18831915
18841916 /// Parse an argument in a lambda header e.g. |arg, arg|
18851917 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" ) ) ?;
18871919 let t = if self . eat ( & token:: Colon ) {
18881920 self . parse_ty ( ) ?
18891921 } else {
@@ -2440,7 +2472,11 @@ impl<'a> Parser<'a> {
24402472 return Ok ( self . mk_expr ( lo. to ( hi) , ex, attrs) ) ;
24412473 }
24422474 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+ } ) ;
24442480 }
24452481 if self . eat_keyword ( keywords:: Unsafe ) {
24462482 return self . parse_block_expr (
@@ -3746,7 +3782,7 @@ impl<'a> Parser<'a> {
37463782 "`..` can only be used once per tuple or tuple struct pattern" ) ;
37473783 }
37483784 } else if !self . check ( & token:: CloseDelim ( token:: Paren ) ) {
3749- fields. push ( self . parse_pat ( ) ?) ;
3785+ fields. push ( self . parse_pat ( None ) ?) ;
37503786 } else {
37513787 break
37523788 }
@@ -3802,7 +3838,7 @@ impl<'a> Parser<'a> {
38023838 }
38033839 }
38043840
3805- let subpat = self . parse_pat ( ) ?;
3841+ let subpat = self . parse_pat ( None ) ?;
38063842 if before_slice && self . eat ( & token:: DotDot ) {
38073843 slice = Some ( subpat) ;
38083844 before_slice = false ;
@@ -3827,7 +3863,7 @@ impl<'a> Parser<'a> {
38273863 // Parsing a pattern of the form "fieldname: pat"
38283864 let fieldname = self . parse_field_name ( ) ?;
38293865 self . bump ( ) ;
3830- let pat = self . parse_pat ( ) ?;
3866+ let pat = self . parse_pat ( None ) ?;
38313867 hi = pat. span ;
38323868 ( pat, fieldname, false )
38333869 } else {
@@ -4029,7 +4065,7 @@ impl<'a> Parser<'a> {
40294065 /// "top-level" patterns in a match arm, `for` loop, `let`, &c. (in contrast
40304066 /// to subpatterns within such).
40314067 fn parse_top_level_pat ( & mut self ) -> PResult < ' a , P < Pat > > {
4032- let pat = self . parse_pat ( ) ?;
4068+ let pat = self . parse_pat ( None ) ?;
40334069 if self . token == token:: Comma {
40344070 // An unexpected comma after a top-level pattern is a clue that the
40354071 // user (perhaps more accustomed to some other language) forgot the
@@ -4061,13 +4097,17 @@ impl<'a> Parser<'a> {
40614097 }
40624098
40634099 /// 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 )
40664102 }
40674103
40684104 /// Parse a pattern, with a setting whether modern range patterns e.g. `a..=b`, `a..b` are
40694105 /// 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 > > {
40714111 maybe_whole ! ( self , NtPat , |x| x) ;
40724112
40734113 let lo = self . span ;
@@ -4083,7 +4123,7 @@ impl<'a> Parser<'a> {
40834123 err. span_label ( self . span , "unexpected lifetime" ) ;
40844124 return Err ( err) ;
40854125 }
4086- let subpat = self . parse_pat_with_range_pat ( false ) ?;
4126+ let subpat = self . parse_pat_with_range_pat ( false , expected ) ?;
40874127 pat = PatKind :: Ref ( subpat, mutbl) ;
40884128 }
40894129 token:: OpenDelim ( token:: Paren ) => {
@@ -4129,7 +4169,7 @@ impl<'a> Parser<'a> {
41294169 pat = self . parse_pat_ident ( BindingMode :: ByRef ( mutbl) ) ?;
41304170 } else if self . eat_keyword ( keywords:: Box ) {
41314171 // Parse box pat
4132- let subpat = self . parse_pat_with_range_pat ( false ) ?;
4172+ let subpat = self . parse_pat_with_range_pat ( false , None ) ?;
41334173 pat = PatKind :: Box ( subpat) ;
41344174 } else if self . token . is_ident ( ) && !self . token . is_reserved_ident ( ) &&
41354175 self . parse_as_ident ( ) {
@@ -4229,9 +4269,14 @@ impl<'a> Parser<'a> {
42294269 }
42304270 Err ( mut err) => {
42314271 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+ ) ;
42334278 let mut err = self . fatal ( & msg) ;
4234- err. span_label ( self . span , "expected pattern" ) ;
4279+ err. span_label ( self . span , format ! ( "expected {}" , expected ) ) ;
42354280 return Err ( err) ;
42364281 }
42374282 }
@@ -4275,7 +4320,7 @@ impl<'a> Parser<'a> {
42754320 -> PResult < ' a , PatKind > {
42764321 let ident = self . parse_ident ( ) ?;
42774322 let sub = if self . eat ( & token:: At ) {
4278- Some ( self . parse_pat ( ) ?)
4323+ Some ( self . parse_pat ( Some ( "binding pattern" ) ) ?)
42794324 } else {
42804325 None
42814326 } ;
0 commit comments