@@ -46,7 +46,7 @@ use crate::ThinVec;
46
46
use crate :: tokenstream:: { self , DelimSpan , TokenTree , TokenStream , TreeAndJoint } ;
47
47
use crate :: symbol:: { Symbol , keywords} ;
48
48
49
- use errors:: { Applicability , DiagnosticBuilder , DiagnosticId } ;
49
+ use errors:: { Applicability , DiagnosticBuilder , DiagnosticId , FatalError } ;
50
50
use rustc_target:: spec:: abi:: { self , Abi } ;
51
51
use syntax_pos:: { Span , MultiSpan , BytePos , FileName } ;
52
52
use log:: { debug, trace} ;
@@ -256,8 +256,15 @@ pub struct Parser<'a> {
256
256
/// it gets removed from here. Every entry left at the end gets emitted as an independent
257
257
/// error.
258
258
crate unclosed_delims : Vec < UnmatchedBrace > ,
259
+ last_unexpected_token_span : Option < Span > ,
259
260
}
260
261
262
+ impl < ' a > Drop for Parser < ' a > {
263
+ fn drop ( & mut self ) {
264
+ let diag = self . diagnostic ( ) ;
265
+ emit_unclosed_delims ( & mut self . unclosed_delims , diag) ;
266
+ }
267
+ }
261
268
262
269
#[ derive( Clone ) ]
263
270
struct TokenCursor {
@@ -582,6 +589,7 @@ impl<'a> Parser<'a> {
582
589
unmatched_angle_bracket_count : 0 ,
583
590
max_angle_bracket_count : 0 ,
584
591
unclosed_delims : Vec :: new ( ) ,
592
+ last_unexpected_token_span : None ,
585
593
} ;
586
594
587
595
let tok = parser. next_tok ( ) ;
@@ -775,6 +783,8 @@ impl<'a> Parser<'a> {
775
783
} else if inedible. contains ( & self . token ) {
776
784
// leave it in the input
777
785
Ok ( false )
786
+ } else if self . last_unexpected_token_span == Some ( self . span ) {
787
+ FatalError . raise ( ) ;
778
788
} else {
779
789
let mut expected = edible. iter ( )
780
790
. map ( |x| TokenType :: Token ( x. clone ( ) ) )
@@ -802,6 +812,7 @@ impl<'a> Parser<'a> {
802
812
( self . sess . source_map ( ) . next_point ( self . prev_span ) ,
803
813
format ! ( "expected {} here" , expect) ) )
804
814
} ;
815
+ self . last_unexpected_token_span = Some ( self . span ) ;
805
816
let mut err = self . fatal ( & msg_exp) ;
806
817
if self . token . is_ident_named ( "and" ) {
807
818
err. span_suggestion_short (
@@ -1497,9 +1508,13 @@ impl<'a> Parser<'a> {
1497
1508
pub fn parse_trait_item ( & mut self , at_end : & mut bool ) -> PResult < ' a , TraitItem > {
1498
1509
maybe_whole ! ( self , NtTraitItem , |x| x) ;
1499
1510
let attrs = self . parse_outer_attributes ( ) ?;
1511
+ let mut unclosed_delims = vec ! [ ] ;
1500
1512
let ( mut item, tokens) = self . collect_tokens ( |this| {
1501
- this. parse_trait_item_ ( at_end, attrs)
1513
+ let item = this. parse_trait_item_ ( at_end, attrs) ;
1514
+ unclosed_delims. append ( & mut this. unclosed_delims ) ;
1515
+ item
1502
1516
} ) ?;
1517
+ self . unclosed_delims . append ( & mut unclosed_delims) ;
1503
1518
// See `parse_item` for why this clause is here.
1504
1519
if !item. attrs . iter ( ) . any ( |attr| attr. style == AttrStyle :: Inner ) {
1505
1520
item. tokens = Some ( tokens) ;
@@ -6333,7 +6348,10 @@ impl<'a> Parser<'a> {
6333
6348
fn_inputs. append ( & mut input) ;
6334
6349
( fn_inputs, recovered)
6335
6350
} else {
6336
- return self . unexpected ( ) ;
6351
+ match self . expect_one_of ( & [ ] , & [ ] ) {
6352
+ Err ( err) => return Err ( err) ,
6353
+ Ok ( recovered) => ( vec ! [ self_arg] , recovered) ,
6354
+ }
6337
6355
}
6338
6356
} else {
6339
6357
self . parse_seq_to_before_end ( & token:: CloseDelim ( token:: Paren ) , sep, parse_arg_fn) ?
@@ -6459,9 +6477,13 @@ impl<'a> Parser<'a> {
6459
6477
pub fn parse_impl_item ( & mut self , at_end : & mut bool ) -> PResult < ' a , ImplItem > {
6460
6478
maybe_whole ! ( self , NtImplItem , |x| x) ;
6461
6479
let attrs = self . parse_outer_attributes ( ) ?;
6480
+ let mut unclosed_delims = vec ! [ ] ;
6462
6481
let ( mut item, tokens) = self . collect_tokens ( |this| {
6463
- this. parse_impl_item_ ( at_end, attrs)
6482
+ let item = this. parse_impl_item_ ( at_end, attrs) ;
6483
+ unclosed_delims. append ( & mut this. unclosed_delims ) ;
6484
+ item
6464
6485
} ) ?;
6486
+ self . unclosed_delims . append ( & mut unclosed_delims) ;
6465
6487
6466
6488
// See `parse_item` for why this clause is here.
6467
6489
if !item. attrs . iter ( ) . any ( |attr| attr. style == AttrStyle :: Inner ) {
@@ -7781,9 +7803,13 @@ impl<'a> Parser<'a> {
7781
7803
macros_allowed : bool ,
7782
7804
attributes_allowed : bool ,
7783
7805
) -> PResult < ' a , Option < P < Item > > > {
7806
+ let mut unclosed_delims = vec ! [ ] ;
7784
7807
let ( ret, tokens) = self . collect_tokens ( |this| {
7785
- this. parse_item_implementation ( attrs, macros_allowed, attributes_allowed)
7808
+ let item = this. parse_item_implementation ( attrs, macros_allowed, attributes_allowed) ;
7809
+ unclosed_delims. append ( & mut this. unclosed_delims ) ;
7810
+ item
7786
7811
} ) ?;
7812
+ self . unclosed_delims . append ( & mut unclosed_delims) ;
7787
7813
7788
7814
// Once we've parsed an item and recorded the tokens we got while
7789
7815
// parsing we may want to store `tokens` into the item we're about to
@@ -8539,8 +8565,6 @@ impl<'a> Parser<'a> {
8539
8565
module : self . parse_mod_items ( & token:: Eof , lo) ?,
8540
8566
span : lo. to ( self . span ) ,
8541
8567
} ) ;
8542
- emit_unclosed_delims ( & self . unclosed_delims , self . diagnostic ( ) ) ;
8543
- self . unclosed_delims . clear ( ) ;
8544
8568
krate
8545
8569
}
8546
8570
@@ -8571,8 +8595,8 @@ impl<'a> Parser<'a> {
8571
8595
}
8572
8596
}
8573
8597
8574
- pub fn emit_unclosed_delims ( unclosed_delims : & [ UnmatchedBrace ] , handler : & errors:: Handler ) {
8575
- for unmatched in unclosed_delims {
8598
+ pub fn emit_unclosed_delims ( unclosed_delims : & mut Vec < UnmatchedBrace > , handler : & errors:: Handler ) {
8599
+ for unmatched in unclosed_delims. iter ( ) {
8576
8600
let mut err = handler. struct_span_err ( unmatched. found_span , & format ! (
8577
8601
"incorrect close delimiter: `{}`" ,
8578
8602
pprust:: token_to_string( & token:: Token :: CloseDelim ( unmatched. found_delim) ) ,
@@ -8586,4 +8610,5 @@ pub fn emit_unclosed_delims(unclosed_delims: &[UnmatchedBrace], handler: &errors
8586
8610
}
8587
8611
err. emit ( ) ;
8588
8612
}
8613
+ unclosed_delims. clear ( ) ;
8589
8614
}
0 commit comments