@@ -9,20 +9,19 @@ mod path;
99pub use path:: PathStyle ;
1010mod stmt;
1111mod generics;
12+ use super :: diagnostics:: Error ;
1213
1314use 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 ,
1717} ;
1818use crate :: parse:: { ParseSess , PResult , Directory , DirectoryOwnership , SeqSep , literal, token} ;
19- use crate :: parse:: diagnostics:: { Error , dummy_arg} ;
2019use crate :: parse:: lexer:: UnmatchedBrace ;
2120use crate :: parse:: lexer:: comments:: { doc_comment_style, strip_doc_comment_decoration} ;
2221use crate :: parse:: token:: { Token , TokenKind , DelimToken } ;
2322use crate :: print:: pprust;
2423use crate :: ptr:: P ;
25- use crate :: source_map:: { self , respan} ;
24+ use crate :: source_map:: respan;
2625use crate :: symbol:: { kw, sym, Symbol } ;
2726use crate :: tokenstream:: { self , DelimSpan , TokenTree , TokenStream , TreeAndJoint } ;
2827use crate :: ThinVec ;
@@ -56,17 +55,6 @@ crate enum BlockMode {
5655 Ignore ,
5756}
5857
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-
7058/// Like `maybe_whole_expr`, but for things other than expressions.
7159#[ macro_export]
7260macro_rules! maybe_whole {
@@ -1105,271 +1093,6 @@ impl<'a> Parser<'a> {
11051093 res
11061094 }
11071095
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-
13731096 fn is_crate_vis ( & self ) -> bool {
13741097 self . token . is_keyword ( kw:: Crate ) && self . look_ahead ( 1 , |t| t != & token:: ModSep )
13751098 }
0 commit comments