@@ -85,12 +85,18 @@ pub enum PathStyle {
8585 Expr ,
8686}
8787
88- #[ derive( Clone , Copy , PartialEq ) ]
88+ #[ derive( Clone , Copy , Debug , PartialEq ) ]
8989pub enum SemiColonMode {
9090 Break ,
9191 Ignore ,
9292}
9393
94+ #[ derive( Clone , Copy , Debug , PartialEq ) ]
95+ pub enum BlockMode {
96+ Break ,
97+ Ignore ,
98+ }
99+
94100/// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
95101/// dropped into the token stream, which happens while parsing the result of
96102/// macro expansion). Placement of these is not as complex as I feared it would
@@ -1204,7 +1210,7 @@ impl<'a> Parser<'a> {
12041210 }
12051211
12061212 /// Parse the items in a trait declaration
1207- pub fn parse_trait_item ( & mut self ) -> PResult < ' a , TraitItem > {
1213+ pub fn parse_trait_item ( & mut self , at_end : & mut bool ) -> PResult < ' a , TraitItem > {
12081214 maybe_whole ! ( self , NtTraitItem , |x| x) ;
12091215 let mut attrs = self . parse_outer_attributes ( ) ?;
12101216 let lo = self . span ;
@@ -1214,7 +1220,7 @@ impl<'a> Parser<'a> {
12141220 self . expect ( & token:: Semi ) ?;
12151221 ( ident, TraitItemKind :: Type ( bounds, default) )
12161222 } else if self . is_const_item ( ) {
1217- self . expect_keyword ( keywords:: Const ) ?;
1223+ self . expect_keyword ( keywords:: Const ) ?;
12181224 let ident = self . parse_ident ( ) ?;
12191225 self . expect ( & token:: Colon ) ?;
12201226 let ty = self . parse_ty ( ) ?;
@@ -1231,9 +1237,17 @@ impl<'a> Parser<'a> {
12311237 } else if self . token . is_path_start ( ) {
12321238 // trait item macro.
12331239 // code copied from parse_macro_use_or_failure... abstraction!
1240+ let prev_span = self . prev_span ;
12341241 let lo = self . span ;
12351242 let pth = self . parse_path ( PathStyle :: Mod ) ?;
1236- self . expect ( & token:: Not ) ?;
1243+
1244+ if pth. segments . len ( ) == 1 {
1245+ if !self . eat ( & token:: Not ) {
1246+ return Err ( self . missing_assoc_item_kind_err ( "trait" , prev_span) ) ;
1247+ }
1248+ } else {
1249+ self . expect ( & token:: Not ) ?;
1250+ }
12371251
12381252 // eat a matched-delimiter token tree:
12391253 let ( delim, tts) = self . expect_delimited_token_tree ( ) ?;
@@ -1246,25 +1260,7 @@ impl<'a> Parser<'a> {
12461260 } else {
12471261 let ( constness, unsafety, abi) = match self . parse_fn_front_matter ( ) {
12481262 Ok ( cua) => cua,
1249- Err ( e) => {
1250- loop {
1251- match self . token {
1252- token:: Eof => break ,
1253- token:: CloseDelim ( token:: Brace ) |
1254- token:: Semi => {
1255- self . bump ( ) ;
1256- break ;
1257- }
1258- token:: OpenDelim ( token:: Brace ) => {
1259- self . parse_token_tree ( ) ;
1260- break ;
1261- }
1262- _ => self . bump ( ) ,
1263- }
1264- }
1265-
1266- return Err ( e) ;
1267- }
1263+ Err ( e) => return Err ( e) ,
12681264 } ;
12691265
12701266 let ident = self . parse_ident ( ) ?;
@@ -1289,11 +1285,13 @@ impl<'a> Parser<'a> {
12891285 let body = match self . token {
12901286 token:: Semi => {
12911287 self . bump ( ) ;
1288+ * at_end = true ;
12921289 debug ! ( "parse_trait_methods(): parsing required method" ) ;
12931290 None
12941291 }
12951292 token:: OpenDelim ( token:: Brace ) => {
12961293 debug ! ( "parse_trait_methods(): parsing provided method" ) ;
1294+ * at_end = true ;
12971295 let ( inner_attrs, body) = self . parse_inner_attrs_and_block ( ) ?;
12981296 attrs. extend ( inner_attrs. iter ( ) . cloned ( ) ) ;
12991297 Some ( body)
@@ -1315,18 +1313,6 @@ impl<'a> Parser<'a> {
13151313 } )
13161314 }
13171315
1318-
1319- /// Parse the items in a trait declaration
1320- pub fn parse_trait_items ( & mut self ) -> PResult < ' a , Vec < TraitItem > > {
1321- self . parse_unspanned_seq (
1322- & token:: OpenDelim ( token:: Brace ) ,
1323- & token:: CloseDelim ( token:: Brace ) ,
1324- SeqSep :: none ( ) ,
1325- |p| -> PResult < ' a , TraitItem > {
1326- p. parse_trait_item ( )
1327- } )
1328- }
1329-
13301316 /// Parse optional return type [ -> TY ] in function decl
13311317 pub fn parse_ret_ty ( & mut self ) -> PResult < ' a , FunctionRetTy > {
13321318 if self . eat ( & token:: RArrow ) {
@@ -3641,22 +3627,33 @@ impl<'a> Parser<'a> {
36413627 //
36423628 // We terminate when we find an unmatched `}` (without consuming it).
36433629 fn recover_stmt ( & mut self ) {
3644- self . recover_stmt_ ( SemiColonMode :: Ignore )
3630+ self . recover_stmt_ ( SemiColonMode :: Ignore , BlockMode :: Ignore )
36453631 }
3632+
36463633 // If `break_on_semi` is `Break`, then we will stop consuming tokens after
36473634 // finding (and consuming) a `;` outside of `{}` or `[]` (note that this is
36483635 // approximate - it can mean we break too early due to macros, but that
36493636 // shoud only lead to sub-optimal recovery, not inaccurate parsing).
3650- fn recover_stmt_ ( & mut self , break_on_semi : SemiColonMode ) {
3637+ //
3638+ // If `break_on_block` is `Break`, then we will stop consuming tokens
3639+ // after finding (and consuming) a brace-delimited block.
3640+ fn recover_stmt_ ( & mut self , break_on_semi : SemiColonMode , break_on_block : BlockMode ) {
36513641 let mut brace_depth = 0 ;
36523642 let mut bracket_depth = 0 ;
3653- debug ! ( "recover_stmt_ enter loop" ) ;
3643+ let mut in_block = false ;
3644+ debug ! ( "recover_stmt_ enter loop (semi={:?}, block={:?})" ,
3645+ break_on_semi, break_on_block) ;
36543646 loop {
36553647 debug ! ( "recover_stmt_ loop {:?}" , self . token) ;
36563648 match self . token {
36573649 token:: OpenDelim ( token:: DelimToken :: Brace ) => {
36583650 brace_depth += 1 ;
36593651 self . bump ( ) ;
3652+ if break_on_block == BlockMode :: Break &&
3653+ brace_depth == 1 &&
3654+ bracket_depth == 0 {
3655+ in_block = true ;
3656+ }
36603657 }
36613658 token:: OpenDelim ( token:: DelimToken :: Bracket ) => {
36623659 bracket_depth += 1 ;
@@ -3669,6 +3666,10 @@ impl<'a> Parser<'a> {
36693666 }
36703667 brace_depth -= 1 ;
36713668 self . bump ( ) ;
3669+ if in_block && bracket_depth == 0 && brace_depth == 0 {
3670+ debug ! ( "recover_stmt_ return - block end {:?}" , self . token) ;
3671+ return ;
3672+ }
36723673 }
36733674 token:: CloseDelim ( token:: DelimToken :: Bracket ) => {
36743675 bracket_depth -= 1 ;
@@ -3700,7 +3701,7 @@ impl<'a> Parser<'a> {
37003701 fn parse_stmt_ ( & mut self , macro_legacy_warnings : bool ) -> Option < Stmt > {
37013702 self . parse_stmt_without_recovery ( macro_legacy_warnings) . unwrap_or_else ( |mut e| {
37023703 e. emit ( ) ;
3703- self . recover_stmt_ ( SemiColonMode :: Break ) ;
3704+ self . recover_stmt_ ( SemiColonMode :: Break , BlockMode :: Ignore ) ;
37043705 None
37053706 } )
37063707 }
@@ -3974,7 +3975,7 @@ impl<'a> Parser<'a> {
39743975 e. span_suggestion ( stmt_span, "try placing this code inside a block" , sugg) ;
39753976 }
39763977 Err ( mut e) => {
3977- self . recover_stmt_ ( SemiColonMode :: Break ) ;
3978+ self . recover_stmt_ ( SemiColonMode :: Break , BlockMode :: Ignore ) ;
39783979 self . cancel ( & mut e) ;
39793980 }
39803981 _ => ( )
@@ -4663,7 +4664,7 @@ impl<'a> Parser<'a> {
46634664 }
46644665
46654666 /// Parse an impl item.
4666- pub fn parse_impl_item ( & mut self ) -> PResult < ' a , ImplItem > {
4667+ pub fn parse_impl_item ( & mut self , at_end : & mut bool ) -> PResult < ' a , ImplItem > {
46674668 maybe_whole ! ( self , NtImplItem , |x| x) ;
46684669
46694670 let mut attrs = self . parse_outer_attributes ( ) ?;
@@ -4686,7 +4687,7 @@ impl<'a> Parser<'a> {
46864687 self . expect ( & token:: Semi ) ?;
46874688 ( name, ast:: ImplItemKind :: Const ( typ, expr) )
46884689 } else {
4689- let ( name, inner_attrs, node) = self . parse_impl_method ( & vis) ?;
4690+ let ( name, inner_attrs, node) = self . parse_impl_method ( & vis, at_end ) ?;
46904691 attrs. extend ( inner_attrs) ;
46914692 ( name, node)
46924693 } ;
@@ -4731,43 +4732,50 @@ impl<'a> Parser<'a> {
47314732 }
47324733 }
47334734
4735+ fn missing_assoc_item_kind_err ( & mut self , item_type : & str , prev_span : Span )
4736+ -> DiagnosticBuilder < ' a >
4737+ {
4738+ // Given this code `path(`, it seems like this is not
4739+ // setting the visibility of a macro invocation, but rather
4740+ // a mistyped method declaration.
4741+ // Create a diagnostic pointing out that `fn` is missing.
4742+ //
4743+ // x | pub path(&self) {
4744+ // | ^ missing `fn`, `type`, or `const`
4745+ // pub path(
4746+ // ^^ `sp` below will point to this
4747+ let sp = prev_span. between ( self . prev_span ) ;
4748+ let mut err = self . diagnostic ( ) . struct_span_err (
4749+ sp,
4750+ & format ! ( "missing `fn`, `type`, or `const` for {}-item declaration" ,
4751+ item_type) ) ;
4752+ err. span_label ( sp, & "missing `fn`, `type`, or `const`" ) ;
4753+ err
4754+ }
4755+
47344756 /// Parse a method or a macro invocation in a trait impl.
4735- fn parse_impl_method ( & mut self , vis : & Visibility )
4757+ fn parse_impl_method ( & mut self , vis : & Visibility , at_end : & mut bool )
47364758 -> PResult < ' a , ( Ident , Vec < ast:: Attribute > , ast:: ImplItemKind ) > {
47374759 // code copied from parse_macro_use_or_failure... abstraction!
47384760 if self . token . is_path_start ( ) {
47394761 // Method macro.
47404762
47414763 let prev_span = self . prev_span ;
4742- // Before complaining about trying to set a macro as `pub`,
4743- // check if `!` comes after the path.
4744- let err = self . complain_if_pub_macro_diag ( & vis, prev_span) ;
47454764
47464765 let lo = self . span ;
47474766 let pth = self . parse_path ( PathStyle :: Mod ) ?;
4748- let bang_err = self . expect ( & token:: Not ) ;
4749- if let Err ( mut err) = err {
4750- if let Err ( mut bang_err) = bang_err {
4751- // Given this code `pub path(`, it seems like this is not setting the
4752- // visibility of a macro invocation, but rather a mistyped method declaration.
4753- // Create a diagnostic pointing out that `fn` is missing.
4754- //
4755- // x | pub path(&self) {
4756- // | ^ missing `fn` for method declaration
4757-
4758- err. cancel ( ) ;
4759- bang_err. cancel ( ) ;
4760- // pub path(
4761- // ^^ `sp` below will point to this
4762- let sp = prev_span. between ( self . prev_span ) ;
4763- err = self . diagnostic ( )
4764- . struct_span_err ( sp, "missing `fn` for method declaration" ) ;
4765- err. span_label ( sp, & "missing `fn`" ) ;
4767+ if pth. segments . len ( ) == 1 {
4768+ if !self . eat ( & token:: Not ) {
4769+ return Err ( self . missing_assoc_item_kind_err ( "impl" , prev_span) ) ;
47664770 }
4767- return Err ( err) ;
4771+ } else {
4772+ self . expect ( & token:: Not ) ?;
47684773 }
47694774
4775+ self . complain_if_pub_macro ( & vis, prev_span) ;
4776+
47704777 // eat a matched-delimiter token tree:
4778+ * at_end = true ;
47714779 let ( delim, tts) = self . expect_delimited_token_tree ( ) ?;
47724780 if delim != token:: Brace {
47734781 self . expect ( & token:: Semi ) ?
@@ -4781,6 +4789,7 @@ impl<'a> Parser<'a> {
47814789 let mut generics = self . parse_generics ( ) ?;
47824790 let decl = self . parse_fn_decl_with_self ( |p| p. parse_arg ( ) ) ?;
47834791 generics. where_clause = self . parse_where_clause ( ) ?;
4792+ * at_end = true ;
47844793 let ( inner_attrs, body) = self . parse_inner_attrs_and_block ( ) ?;
47854794 Ok ( ( ident, inner_attrs, ast:: ImplItemKind :: Method ( ast:: MethodSig {
47864795 generics : generics,
@@ -4806,8 +4815,21 @@ impl<'a> Parser<'a> {
48064815
48074816 tps. where_clause = self . parse_where_clause ( ) ?;
48084817
4809- let meths = self . parse_trait_items ( ) ?;
4810- Ok ( ( ident, ItemKind :: Trait ( unsafety, tps, bounds, meths) , None ) )
4818+ self . expect ( & token:: OpenDelim ( token:: Brace ) ) ?;
4819+ let mut trait_items = vec ! [ ] ;
4820+ while !self . eat ( & token:: CloseDelim ( token:: Brace ) ) {
4821+ let mut at_end = false ;
4822+ match self . parse_trait_item ( & mut at_end) {
4823+ Ok ( item) => trait_items. push ( item) ,
4824+ Err ( mut e) => {
4825+ e. emit ( ) ;
4826+ if !at_end {
4827+ self . recover_stmt_ ( SemiColonMode :: Break , BlockMode :: Break ) ;
4828+ }
4829+ }
4830+ }
4831+ }
4832+ Ok ( ( ident, ItemKind :: Trait ( unsafety, tps, bounds, trait_items) , None ) )
48114833 }
48124834
48134835 /// Parses items implementations variants
@@ -4882,7 +4904,16 @@ impl<'a> Parser<'a> {
48824904
48834905 let mut impl_items = vec ! [ ] ;
48844906 while !self . eat ( & token:: CloseDelim ( token:: Brace ) ) {
4885- impl_items. push ( self . parse_impl_item ( ) ?) ;
4907+ let mut at_end = false ;
4908+ match self . parse_impl_item ( & mut at_end) {
4909+ Ok ( item) => impl_items. push ( item) ,
4910+ Err ( mut e) => {
4911+ e. emit ( ) ;
4912+ if !at_end {
4913+ self . recover_stmt_ ( SemiColonMode :: Break , BlockMode :: Break ) ;
4914+ }
4915+ }
4916+ }
48864917 }
48874918
48884919 Ok ( ( keywords:: Invalid . ident ( ) ,
0 commit comments