@@ -9,20 +9,19 @@ mod path;
9
9
pub use path:: PathStyle ;
10
10
mod stmt;
11
11
mod generics;
12
+ use super :: diagnostics:: Error ;
12
13
13
14
use crate :: ast:: {
14
- self , DUMMY_NODE_ID , AttrStyle , Attribute , BindingMode , CrateSugar , Ident ,
15
- IsAsync , MacDelimiter , Mutability , Param , StrStyle , SelfKind , TyKind , Visibility ,
16
- VisibilityKind , Unsafety ,
15
+ self , DUMMY_NODE_ID , AttrStyle , Attribute , CrateSugar , Ident ,
16
+ IsAsync , MacDelimiter , Mutability , StrStyle , Visibility , VisibilityKind , Unsafety ,
17
17
} ;
18
18
use crate :: parse:: { ParseSess , PResult , Directory , DirectoryOwnership , SeqSep , literal, token} ;
19
- use crate :: parse:: diagnostics:: { Error , dummy_arg} ;
20
19
use crate :: parse:: lexer:: UnmatchedBrace ;
21
20
use crate :: parse:: lexer:: comments:: { doc_comment_style, strip_doc_comment_decoration} ;
22
21
use crate :: parse:: token:: { Token , TokenKind , DelimToken } ;
23
22
use crate :: print:: pprust;
24
23
use crate :: ptr:: P ;
25
- use crate :: source_map:: { self , respan} ;
24
+ use crate :: source_map:: respan;
26
25
use crate :: symbol:: { kw, sym, Symbol } ;
27
26
use crate :: tokenstream:: { self , DelimSpan , TokenTree , TokenStream , TreeAndJoint } ;
28
27
use crate :: ThinVec ;
@@ -56,17 +55,6 @@ crate enum BlockMode {
56
55
Ignore ,
57
56
}
58
57
59
- /// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
60
- struct ParamCfg {
61
- /// Is `self` is allowed as the first parameter?
62
- is_self_allowed : bool ,
63
- /// Is `...` allowed as the tail of the parameter list?
64
- allow_c_variadic : bool ,
65
- /// `is_name_required` decides if, per-parameter,
66
- /// the parameter must have a pattern or just a type.
67
- is_name_required : fn ( & token:: Token ) -> bool ,
68
- }
69
-
70
58
/// Like `maybe_whole_expr`, but for things other than expressions.
71
59
#[ macro_export]
72
60
macro_rules! maybe_whole {
@@ -1105,271 +1093,6 @@ impl<'a> Parser<'a> {
1105
1093
res
1106
1094
}
1107
1095
1108
- /// Parses the parameter list of a function, including the `(` and `)` delimiters.
1109
- fn parse_fn_params ( & mut self , mut cfg : ParamCfg ) -> PResult < ' a , Vec < Param > > {
1110
- let sp = self . token . span ;
1111
- let is_trait_item = cfg. is_self_allowed ;
1112
- let mut c_variadic = false ;
1113
- // Parse the arguments, starting out with `self` being possibly allowed...
1114
- let ( params, _) = self . parse_paren_comma_seq ( |p| {
1115
- let param = p. parse_param_general ( & cfg, is_trait_item) ;
1116
- // ...now that we've parsed the first argument, `self` is no longer allowed.
1117
- cfg. is_self_allowed = false ;
1118
-
1119
- match param {
1120
- Ok ( param) => Ok (
1121
- if let TyKind :: CVarArgs = param. ty . kind {
1122
- c_variadic = true ;
1123
- if p. token != token:: CloseDelim ( token:: Paren ) {
1124
- p. span_err (
1125
- p. token . span ,
1126
- "`...` must be the last argument of a C-variadic function" ,
1127
- ) ;
1128
- // FIXME(eddyb) this should probably still push `CVarArgs`.
1129
- // Maybe AST validation/HIR lowering should emit the above error?
1130
- None
1131
- } else {
1132
- Some ( param)
1133
- }
1134
- } else {
1135
- Some ( param)
1136
- }
1137
- ) ,
1138
- Err ( mut e) => {
1139
- e. emit ( ) ;
1140
- let lo = p. prev_span ;
1141
- // Skip every token until next possible arg or end.
1142
- p. eat_to_tokens ( & [ & token:: Comma , & token:: CloseDelim ( token:: Paren ) ] ) ;
1143
- // Create a placeholder argument for proper arg count (issue #34264).
1144
- let span = lo. to ( p. prev_span ) ;
1145
- Ok ( Some ( dummy_arg ( Ident :: new ( kw:: Invalid , span) ) ) )
1146
- }
1147
- }
1148
- } ) ?;
1149
-
1150
- let mut params: Vec < _ > = params. into_iter ( ) . filter_map ( |x| x) . collect ( ) ;
1151
-
1152
- // Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
1153
- self . deduplicate_recovered_params_names ( & mut params) ;
1154
-
1155
- if c_variadic && params. len ( ) <= 1 {
1156
- self . span_err (
1157
- sp,
1158
- "C-variadic function must be declared with at least one named argument" ,
1159
- ) ;
1160
- }
1161
-
1162
- Ok ( params)
1163
- }
1164
-
1165
- /// Skips unexpected attributes and doc comments in this position and emits an appropriate
1166
- /// error.
1167
- /// This version of parse param doesn't necessarily require identifier names.
1168
- fn parse_param_general ( & mut self , cfg : & ParamCfg , is_trait_item : bool ) -> PResult < ' a , Param > {
1169
- let lo = self . token . span ;
1170
- let attrs = self . parse_outer_attributes ( ) ?;
1171
-
1172
- // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
1173
- if let Some ( mut param) = self . parse_self_param ( ) ? {
1174
- param. attrs = attrs. into ( ) ;
1175
- return if cfg. is_self_allowed {
1176
- Ok ( param)
1177
- } else {
1178
- self . recover_bad_self_param ( param, is_trait_item)
1179
- } ;
1180
- }
1181
-
1182
- let is_name_required = match self . token . kind {
1183
- token:: DotDotDot => false ,
1184
- _ => ( cfg. is_name_required ) ( & self . token ) ,
1185
- } ;
1186
- let ( pat, ty) = if is_name_required || self . is_named_param ( ) {
1187
- debug ! ( "parse_param_general parse_pat (is_name_required:{})" , is_name_required) ;
1188
-
1189
- let pat = self . parse_fn_param_pat ( ) ?;
1190
- if let Err ( mut err) = self . expect ( & token:: Colon ) {
1191
- return if let Some ( ident) = self . parameter_without_type (
1192
- & mut err,
1193
- pat,
1194
- is_name_required,
1195
- cfg. is_self_allowed ,
1196
- is_trait_item,
1197
- ) {
1198
- err. emit ( ) ;
1199
- Ok ( dummy_arg ( ident) )
1200
- } else {
1201
- Err ( err)
1202
- } ;
1203
- }
1204
-
1205
- self . eat_incorrect_doc_comment_for_param_type ( ) ;
1206
- ( pat, self . parse_ty_common ( true , true , cfg. allow_c_variadic ) ?)
1207
- } else {
1208
- debug ! ( "parse_param_general ident_to_pat" ) ;
1209
- let parser_snapshot_before_ty = self . clone ( ) ;
1210
- self . eat_incorrect_doc_comment_for_param_type ( ) ;
1211
- let mut ty = self . parse_ty_common ( true , true , cfg. allow_c_variadic ) ;
1212
- if ty. is_ok ( ) && self . token != token:: Comma &&
1213
- self . token != token:: CloseDelim ( token:: Paren ) {
1214
- // This wasn't actually a type, but a pattern looking like a type,
1215
- // so we are going to rollback and re-parse for recovery.
1216
- ty = self . unexpected ( ) ;
1217
- }
1218
- match ty {
1219
- Ok ( ty) => {
1220
- let ident = Ident :: new ( kw:: Invalid , self . prev_span ) ;
1221
- let bm = BindingMode :: ByValue ( Mutability :: Immutable ) ;
1222
- let pat = self . mk_pat_ident ( ty. span , bm, ident) ;
1223
- ( pat, ty)
1224
- }
1225
- // If this is a C-variadic argument and we hit an error, return the error.
1226
- Err ( err) if self . token == token:: DotDotDot => return Err ( err) ,
1227
- // Recover from attempting to parse the argument as a type without pattern.
1228
- Err ( mut err) => {
1229
- err. cancel ( ) ;
1230
- mem:: replace ( self , parser_snapshot_before_ty) ;
1231
- self . recover_arg_parse ( ) ?
1232
- }
1233
- }
1234
- } ;
1235
-
1236
- let span = lo. to ( self . token . span ) ;
1237
-
1238
- Ok ( Param {
1239
- attrs : attrs. into ( ) ,
1240
- id : ast:: DUMMY_NODE_ID ,
1241
- is_placeholder : false ,
1242
- pat,
1243
- span,
1244
- ty,
1245
- } )
1246
- }
1247
-
1248
- /// Returns the parsed optional self parameter and whether a self shortcut was used.
1249
- ///
1250
- /// See `parse_self_param_with_attrs` to collect attributes.
1251
- fn parse_self_param ( & mut self ) -> PResult < ' a , Option < Param > > {
1252
- // Extract an identifier *after* having confirmed that the token is one.
1253
- let expect_self_ident = |this : & mut Self | {
1254
- match this. token . kind {
1255
- // Preserve hygienic context.
1256
- token:: Ident ( name, _) => {
1257
- let span = this. token . span ;
1258
- this. bump ( ) ;
1259
- Ident :: new ( name, span)
1260
- }
1261
- _ => unreachable ! ( ) ,
1262
- }
1263
- } ;
1264
- // Is `self` `n` tokens ahead?
1265
- let is_isolated_self = |this : & Self , n| {
1266
- this. is_keyword_ahead ( n, & [ kw:: SelfLower ] )
1267
- && this. look_ahead ( n + 1 , |t| t != & token:: ModSep )
1268
- } ;
1269
- // Is `mut self` `n` tokens ahead?
1270
- let is_isolated_mut_self = |this : & Self , n| {
1271
- this. is_keyword_ahead ( n, & [ kw:: Mut ] )
1272
- && is_isolated_self ( this, n + 1 )
1273
- } ;
1274
- // Parse `self` or `self: TYPE`. We already know the current token is `self`.
1275
- let parse_self_possibly_typed = |this : & mut Self , m| {
1276
- let eself_ident = expect_self_ident ( this) ;
1277
- let eself_hi = this. prev_span ;
1278
- let eself = if this. eat ( & token:: Colon ) {
1279
- SelfKind :: Explicit ( this. parse_ty ( ) ?, m)
1280
- } else {
1281
- SelfKind :: Value ( m)
1282
- } ;
1283
- Ok ( ( eself, eself_ident, eself_hi) )
1284
- } ;
1285
- // Recover for the grammar `*self`, `*const self`, and `*mut self`.
1286
- let recover_self_ptr = |this : & mut Self | {
1287
- let msg = "cannot pass `self` by raw pointer" ;
1288
- let span = this. token . span ;
1289
- this. struct_span_err ( span, msg)
1290
- . span_label ( span, msg)
1291
- . emit ( ) ;
1292
-
1293
- Ok ( ( SelfKind :: Value ( Mutability :: Immutable ) , expect_self_ident ( this) , this. prev_span ) )
1294
- } ;
1295
-
1296
- // Parse optional `self` parameter of a method.
1297
- // Only a limited set of initial token sequences is considered `self` parameters; anything
1298
- // else is parsed as a normal function parameter list, so some lookahead is required.
1299
- let eself_lo = self . token . span ;
1300
- let ( eself, eself_ident, eself_hi) = match self . token . kind {
1301
- token:: BinOp ( token:: And ) => {
1302
- let eself = if is_isolated_self ( self , 1 ) {
1303
- // `&self`
1304
- self . bump ( ) ;
1305
- SelfKind :: Region ( None , Mutability :: Immutable )
1306
- } else if is_isolated_mut_self ( self , 1 ) {
1307
- // `&mut self`
1308
- self . bump ( ) ;
1309
- self . bump ( ) ;
1310
- SelfKind :: Region ( None , Mutability :: Mutable )
1311
- } else if self . look_ahead ( 1 , |t| t. is_lifetime ( ) ) && is_isolated_self ( self , 2 ) {
1312
- // `&'lt self`
1313
- self . bump ( ) ;
1314
- let lt = self . expect_lifetime ( ) ;
1315
- SelfKind :: Region ( Some ( lt) , Mutability :: Immutable )
1316
- } else if self . look_ahead ( 1 , |t| t. is_lifetime ( ) ) && is_isolated_mut_self ( self , 2 ) {
1317
- // `&'lt mut self`
1318
- self . bump ( ) ;
1319
- let lt = self . expect_lifetime ( ) ;
1320
- self . bump ( ) ;
1321
- SelfKind :: Region ( Some ( lt) , Mutability :: Mutable )
1322
- } else {
1323
- // `¬_self`
1324
- return Ok ( None ) ;
1325
- } ;
1326
- ( eself, expect_self_ident ( self ) , self . prev_span )
1327
- }
1328
- // `*self`
1329
- token:: BinOp ( token:: Star ) if is_isolated_self ( self , 1 ) => {
1330
- self . bump ( ) ;
1331
- recover_self_ptr ( self ) ?
1332
- }
1333
- // `*mut self` and `*const self`
1334
- token:: BinOp ( token:: Star ) if
1335
- self . look_ahead ( 1 , |t| t. is_mutability ( ) )
1336
- && is_isolated_self ( self , 2 ) =>
1337
- {
1338
- self . bump ( ) ;
1339
- self . bump ( ) ;
1340
- recover_self_ptr ( self ) ?
1341
- }
1342
- // `self` and `self: TYPE`
1343
- token:: Ident ( ..) if is_isolated_self ( self , 0 ) => {
1344
- parse_self_possibly_typed ( self , Mutability :: Immutable ) ?
1345
- }
1346
- // `mut self` and `mut self: TYPE`
1347
- token:: Ident ( ..) if is_isolated_mut_self ( self , 0 ) => {
1348
- self . bump ( ) ;
1349
- parse_self_possibly_typed ( self , Mutability :: Mutable ) ?
1350
- }
1351
- _ => return Ok ( None ) ,
1352
- } ;
1353
-
1354
- let eself = source_map:: respan ( eself_lo. to ( eself_hi) , eself) ;
1355
- Ok ( Some ( Param :: from_self ( ThinVec :: default ( ) , eself, eself_ident) ) )
1356
- }
1357
-
1358
- fn is_named_param ( & self ) -> bool {
1359
- let offset = match self . token . kind {
1360
- token:: Interpolated ( ref nt) => match * * nt {
1361
- token:: NtPat ( ..) => return self . look_ahead ( 1 , |t| t == & token:: Colon ) ,
1362
- _ => 0 ,
1363
- }
1364
- token:: BinOp ( token:: And ) | token:: AndAnd => 1 ,
1365
- _ if self . token . is_keyword ( kw:: Mut ) => 1 ,
1366
- _ => 0 ,
1367
- } ;
1368
-
1369
- self . look_ahead ( offset, |t| t. is_ident ( ) ) &&
1370
- self . look_ahead ( offset + 1 , |t| t == & token:: Colon )
1371
- }
1372
-
1373
1096
fn is_crate_vis ( & self ) -> bool {
1374
1097
self . token . is_keyword ( kw:: Crate ) && self . look_ahead ( 1 , |t| t != & token:: ModSep )
1375
1098
}
0 commit comments