@@ -10,15 +10,15 @@ use rustc_ast::util::case::Case;
10
10
use rustc_ast:: { self as ast} ;
11
11
use rustc_ast_pretty:: pprust;
12
12
use rustc_errors:: codes:: * ;
13
- use rustc_errors:: { struct_span_code_err , Applicability , PResult , StashKey } ;
13
+ use rustc_errors:: { Applicability , PResult , StashKey , struct_span_code_err } ;
14
14
use rustc_span:: edit_distance:: edit_distance;
15
15
use rustc_span:: edition:: Edition ;
16
- use rustc_span:: symbol:: { kw , sym , Ident , Symbol } ;
17
- use rustc_span:: { source_map , ErrorGuaranteed , Span , DUMMY_SP } ;
18
- use thin_vec:: { thin_vec , ThinVec } ;
16
+ use rustc_span:: symbol:: { Ident , Symbol , kw , sym } ;
17
+ use rustc_span:: { DUMMY_SP , ErrorGuaranteed , Span , source_map } ;
18
+ use thin_vec:: { ThinVec , thin_vec } ;
19
19
use tracing:: debug;
20
20
21
- use super :: diagnostics:: { dummy_arg , ConsumeClosingDelim } ;
21
+ use super :: diagnostics:: { ConsumeClosingDelim , dummy_arg } ;
22
22
use super :: ty:: { AllowPlus , RecoverQPath , RecoverReturnSign } ;
23
23
use super :: {
24
24
AttemptLocalParseRecovery , AttrWrapper , FollowedByType , ForceCollect , Parser , PathStyle ,
@@ -75,6 +75,8 @@ impl<'a> Parser<'a> {
75
75
items. push ( item) ;
76
76
}
77
77
78
+ // The last token should be `term`: either EOF or `}`. If it's not that means that we've had an error
79
+ // parsing an item
78
80
if !self . eat ( term) {
79
81
if !self . maybe_consume_incorrect_semicolon ( items. last ( ) . map ( |x| & * * x) ) {
80
82
let err = self . fallback_incorrect_item ( ) ;
@@ -90,12 +92,15 @@ impl<'a> Parser<'a> {
90
92
/// Tries to parse the item as a statement to provide further diagnostics.
91
93
fn fallback_incorrect_item ( & mut self ) -> rustc_errors:: Diag < ' a > {
92
94
let token_str = super :: token_descr ( & self . token ) ;
93
- let mut err = self
94
- . dcx ( )
95
- . struct_span_err ( self . token . span , format ! ( "expected item, found {token_str}" ) ) ;
95
+ let token_span = self . token . span ;
96
+ let mut err =
97
+ self . dcx ( ) . struct_span_err ( token_span, format ! ( "expected item, found {token_str}" ) ) ;
98
+
99
+ let mut do_default_diag = true ;
96
100
97
101
match self . parse_full_stmt ( AttemptLocalParseRecovery :: No ) {
98
102
Ok ( Some ( stmt) ) => {
103
+ do_default_diag = false ;
99
104
let span = stmt. span ;
100
105
match & stmt. kind {
101
106
StmtKind :: Let ( _) => {
@@ -121,16 +126,22 @@ impl<'a> Parser<'a> {
121
126
) ;
122
127
}
123
128
StmtKind :: Item ( _) | StmtKind :: MacCall ( _) => {
124
- unreachable ! ( "These should be valid. " )
129
+ unreachable ! ( "These should be valid items! " )
125
130
}
126
131
} ;
127
132
}
128
- Ok ( None ) => { } // It's not a statement, not much we can do.
133
+ // It's not a statement, we can't do much recovery.
134
+ Ok ( None ) => { }
129
135
Err ( e) => {
130
136
// We don't really care about an error parsing this statement.
131
137
e. cancel ( ) ;
132
138
}
133
139
}
140
+
141
+ if do_default_diag {
142
+ err. span_label ( token_span, "expected item" ) ;
143
+ }
144
+
134
145
err. note ( "for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>" ) ;
135
146
136
147
err
@@ -490,11 +501,7 @@ impl<'a> Parser<'a> {
490
501
None
491
502
} ;
492
503
493
- if let Some ( err) = err {
494
- Err ( self . dcx ( ) . create_err ( err) )
495
- } else {
496
- Ok ( ( ) )
497
- }
504
+ if let Some ( err) = err { Err ( self . dcx ( ) . create_err ( err) ) } else { Ok ( ( ) ) }
498
505
}
499
506
500
507
fn parse_item_builtin ( & mut self ) -> PResult < ' a , Option < ItemInfo > > {
@@ -1154,11 +1161,7 @@ impl<'a> Parser<'a> {
1154
1161
}
1155
1162
1156
1163
fn parse_rename ( & mut self ) -> PResult < ' a , Option < Ident > > {
1157
- if self . eat_keyword ( kw:: As ) {
1158
- self . parse_ident_or_underscore ( ) . map ( Some )
1159
- } else {
1160
- Ok ( None )
1161
- }
1164
+ if self . eat_keyword ( kw:: As ) { self . parse_ident_or_underscore ( ) . map ( Some ) } else { Ok ( None ) }
1162
1165
}
1163
1166
1164
1167
fn parse_ident_or_underscore ( & mut self ) -> PResult < ' a , Ident > {
@@ -1241,7 +1244,7 @@ impl<'a> Parser<'a> {
1241
1244
mut safety : Safety ,
1242
1245
) -> PResult < ' a , ItemInfo > {
1243
1246
let abi = self . parse_abi ( ) ; // ABI?
1244
- // FIXME: This recovery should be tested better.
1247
+ // FIXME: This recovery should be tested better.
1245
1248
if safety == Safety :: Default
1246
1249
&& self . token . is_keyword ( kw:: Unsafe )
1247
1250
&& self . look_ahead ( 1 , |t| * t == token:: OpenDelim ( Delimiter :: Brace ) )
@@ -1943,10 +1946,10 @@ impl<'a> Parser<'a> {
1943
1946
// Try to recover extra trailing angle brackets
1944
1947
if let TyKind :: Path ( _, Path { segments, .. } ) = & a_var. ty . kind {
1945
1948
if let Some ( last_segment) = segments. last ( ) {
1946
- let guar = self . check_trailing_angle_brackets (
1947
- last_segment ,
1948
- & [ & token:: Comma , & token :: CloseDelim ( Delimiter :: Brace ) ] ,
1949
- ) ;
1949
+ let guar = self . check_trailing_angle_brackets ( last_segment , & [
1950
+ & token :: Comma ,
1951
+ & token:: CloseDelim ( Delimiter :: Brace ) ,
1952
+ ] ) ;
1950
1953
if let Some ( _guar) = guar {
1951
1954
// Handle a case like `Vec<u8>>,` where we can continue parsing fields
1952
1955
// after the comma
@@ -2153,7 +2156,7 @@ impl<'a> Parser<'a> {
2153
2156
self . unexpected ( ) ?;
2154
2157
}
2155
2158
let body = self . parse_token_tree ( ) ; // `MacBody`
2156
- // Convert `MacParams MacBody` into `{ MacParams => MacBody }`.
2159
+ // Convert `MacParams MacBody` into `{ MacParams => MacBody }`.
2157
2160
let bspan = body. span ( ) ;
2158
2161
let arrow = TokenTree :: token_alone ( token:: FatArrow , pspan. between ( bspan) ) ; // `=>`
2159
2162
let tokens = TokenStream :: new ( vec ! [ params, arrow, body] ) ;
0 commit comments