Skip to content

Commit 4737095

Browse files
authored
Rollup merge of rust-lang#65040 - Centril:items-cleanup, r=estebank
syntax: more cleanups in item and function signature parsing Follow up to rust-lang#64910. Best read commit-by-commit. r? @estebank
2 parents 2f0618d + 6b23c22 commit 4737095

File tree

5 files changed

+212
-215
lines changed

5 files changed

+212
-215
lines changed

src/libsyntax/parse/parser.rs

+38-58
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ mod stmt;
1111
mod generics;
1212

1313
use crate::ast::{
14-
self, DUMMY_NODE_ID, AttrStyle, Attribute, BindingMode, CrateSugar, FnDecl, Ident,
14+
self, DUMMY_NODE_ID, AttrStyle, Attribute, BindingMode, CrateSugar, Ident,
1515
IsAsync, MacDelimiter, Mutability, Param, StrStyle, SelfKind, TyKind, Visibility,
1616
VisibilityKind, Unsafety,
1717
};
@@ -56,6 +56,17 @@ crate enum BlockMode {
5656
Ignore,
5757
}
5858

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+
5970
/// Like `maybe_whole_expr`, but for things other than expressions.
6071
#[macro_export]
6172
macro_rules! maybe_whole {
@@ -1094,26 +1105,18 @@ impl<'a> Parser<'a> {
10941105
res
10951106
}
10961107

1097-
fn parse_fn_params(
1098-
&mut self,
1099-
named_params: bool,
1100-
allow_c_variadic: bool,
1101-
) -> PResult<'a, Vec<Param>> {
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>> {
11021110
let sp = self.token.span;
1103-
let do_not_enforce_named_params_for_c_variadic = |token: &token::Token| {
1104-
match token.kind {
1105-
token::DotDotDot => false,
1106-
_ => named_params,
1107-
}
1108-
};
1111+
let is_trait_item = cfg.is_self_allowed;
11091112
let mut c_variadic = false;
1113+
// Parse the arguments, starting out with `self` being possibly allowed...
11101114
let (params, _) = self.parse_paren_comma_seq(|p| {
1111-
match p.parse_param_general(
1112-
false,
1113-
false,
1114-
allow_c_variadic,
1115-
do_not_enforce_named_params_for_c_variadic,
1116-
) {
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 {
11171120
Ok(param) => Ok(
11181121
if let TyKind::CVarArgs = param.ty.kind {
11191122
c_variadic = true;
@@ -1144,7 +1147,10 @@ impl<'a> Parser<'a> {
11441147
}
11451148
})?;
11461149

1147-
let params: Vec<_> = params.into_iter().filter_map(|x| x).collect();
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);
11481154

11491155
if c_variadic && params.len() <= 1 {
11501156
self.span_err(
@@ -1156,79 +1162,53 @@ impl<'a> Parser<'a> {
11561162
Ok(params)
11571163
}
11581164

1159-
/// Parses the parameter list and result type of a function that may have a `self` parameter.
1160-
fn parse_fn_decl_with_self(
1161-
&mut self,
1162-
is_name_required: impl Copy + Fn(&token::Token) -> bool,
1163-
) -> PResult<'a, P<FnDecl>> {
1164-
// Parse the arguments, starting out with `self` being allowed...
1165-
let mut is_self_allowed = true;
1166-
let (mut inputs, _): (Vec<_>, _) = self.parse_paren_comma_seq(|p| {
1167-
let res = p.parse_param_general(is_self_allowed, true, false, is_name_required);
1168-
// ...but now that we've parsed the first argument, `self` is no longer allowed.
1169-
is_self_allowed = false;
1170-
res
1171-
})?;
1172-
1173-
// Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
1174-
self.deduplicate_recovered_params_names(&mut inputs);
1175-
1176-
Ok(P(FnDecl {
1177-
inputs,
1178-
output: self.parse_ret_ty(true)?,
1179-
}))
1180-
}
1181-
11821165
/// Skips unexpected attributes and doc comments in this position and emits an appropriate
11831166
/// error.
11841167
/// This version of parse param doesn't necessarily require identifier names.
1185-
fn parse_param_general(
1186-
&mut self,
1187-
is_self_allowed: bool,
1188-
is_trait_item: bool,
1189-
allow_c_variadic: bool,
1190-
is_name_required: impl Fn(&token::Token) -> bool,
1191-
) -> PResult<'a, Param> {
1168+
fn parse_param_general(&mut self, cfg: &ParamCfg, is_trait_item: bool) -> PResult<'a, Param> {
11921169
let lo = self.token.span;
11931170
let attrs = self.parse_outer_attributes()?;
11941171

11951172
// Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
11961173
if let Some(mut param) = self.parse_self_param()? {
11971174
param.attrs = attrs.into();
1198-
return if is_self_allowed {
1175+
return if cfg.is_self_allowed {
11991176
Ok(param)
12001177
} else {
12011178
self.recover_bad_self_param(param, is_trait_item)
12021179
};
12031180
}
12041181

1205-
let is_name_required = is_name_required(&self.token);
1182+
let is_name_required = match self.token.kind {
1183+
token::DotDotDot => false,
1184+
_ => (cfg.is_name_required)(&self.token),
1185+
};
12061186
let (pat, ty) = if is_name_required || self.is_named_param() {
12071187
debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
12081188

12091189
let pat = self.parse_fn_param_pat()?;
12101190
if let Err(mut err) = self.expect(&token::Colon) {
1211-
if let Some(ident) = self.parameter_without_type(
1191+
return if let Some(ident) = self.parameter_without_type(
12121192
&mut err,
12131193
pat,
12141194
is_name_required,
1215-
is_self_allowed,
1195+
cfg.is_self_allowed,
12161196
is_trait_item,
12171197
) {
12181198
err.emit();
1219-
return Ok(dummy_arg(ident));
1199+
Ok(dummy_arg(ident))
12201200
} else {
1221-
return Err(err);
1222-
}
1201+
Err(err)
1202+
};
12231203
}
12241204

12251205
self.eat_incorrect_doc_comment_for_param_type();
1226-
(pat, self.parse_ty_common(true, true, allow_c_variadic)?)
1206+
(pat, self.parse_ty_common(true, true, cfg.allow_c_variadic)?)
12271207
} else {
12281208
debug!("parse_param_general ident_to_pat");
12291209
let parser_snapshot_before_ty = self.clone();
12301210
self.eat_incorrect_doc_comment_for_param_type();
1231-
let mut ty = self.parse_ty_common(true, true, allow_c_variadic);
1211+
let mut ty = self.parse_ty_common(true, true, cfg.allow_c_variadic);
12321212
if ty.is_ok() && self.token != token::Comma &&
12331213
self.token != token::CloseDelim(token::Paren) {
12341214
// This wasn't actually a type, but a pattern looking like a type,

0 commit comments

Comments
 (0)