Skip to content

Commit 347deac

Browse files
committed
syntax: reorder param parsing to make more sense.
1 parent 0492302 commit 347deac

File tree

1 file changed

+153
-153
lines changed

1 file changed

+153
-153
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 153 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -954,106 +954,6 @@ impl<'a> Parser<'a> {
954954
}
955955
}
956956

957-
fn is_named_param(&self) -> bool {
958-
let offset = match self.token.kind {
959-
token::Interpolated(ref nt) => match **nt {
960-
token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
961-
_ => 0,
962-
}
963-
token::BinOp(token::And) | token::AndAnd => 1,
964-
_ if self.token.is_keyword(kw::Mut) => 1,
965-
_ => 0,
966-
};
967-
968-
self.look_ahead(offset, |t| t.is_ident()) &&
969-
self.look_ahead(offset + 1, |t| t == &token::Colon)
970-
}
971-
972-
/// Skips unexpected attributes and doc comments in this position and emits an appropriate
973-
/// error.
974-
/// This version of parse param doesn't necessarily require identifier names.
975-
fn parse_param_general(
976-
&mut self,
977-
is_self_allowed: bool,
978-
is_trait_item: bool,
979-
allow_c_variadic: bool,
980-
is_name_required: impl Fn(&token::Token) -> bool,
981-
) -> PResult<'a, Param> {
982-
let lo = self.token.span;
983-
let attrs = self.parse_outer_attributes()?;
984-
985-
// Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
986-
if let Some(mut param) = self.parse_self_param()? {
987-
param.attrs = attrs.into();
988-
return if is_self_allowed {
989-
Ok(param)
990-
} else {
991-
self.recover_bad_self_param(param, is_trait_item)
992-
};
993-
}
994-
995-
let is_name_required = is_name_required(&self.token);
996-
let (pat, ty) = if is_name_required || self.is_named_param() {
997-
debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
998-
999-
let pat = self.parse_fn_param_pat()?;
1000-
if let Err(mut err) = self.expect(&token::Colon) {
1001-
if let Some(ident) = self.parameter_without_type(
1002-
&mut err,
1003-
pat,
1004-
is_name_required,
1005-
is_trait_item,
1006-
) {
1007-
err.emit();
1008-
return Ok(dummy_arg(ident));
1009-
} else {
1010-
return Err(err);
1011-
}
1012-
}
1013-
1014-
self.eat_incorrect_doc_comment_for_param_type();
1015-
(pat, self.parse_ty_common(true, true, allow_c_variadic)?)
1016-
} else {
1017-
debug!("parse_param_general ident_to_pat");
1018-
let parser_snapshot_before_ty = self.clone();
1019-
self.eat_incorrect_doc_comment_for_param_type();
1020-
let mut ty = self.parse_ty_common(true, true, allow_c_variadic);
1021-
if ty.is_ok() && self.token != token::Comma &&
1022-
self.token != token::CloseDelim(token::Paren) {
1023-
// This wasn't actually a type, but a pattern looking like a type,
1024-
// so we are going to rollback and re-parse for recovery.
1025-
ty = self.unexpected();
1026-
}
1027-
match ty {
1028-
Ok(ty) => {
1029-
let ident = Ident::new(kw::Invalid, self.prev_span);
1030-
let bm = BindingMode::ByValue(Mutability::Immutable);
1031-
let pat = self.mk_pat_ident(ty.span, bm, ident);
1032-
(pat, ty)
1033-
}
1034-
// If this is a C-variadic argument and we hit an error, return the error.
1035-
Err(err) if self.token == token::DotDotDot => return Err(err),
1036-
// Recover from attempting to parse the argument as a type without pattern.
1037-
Err(mut err) => {
1038-
err.cancel();
1039-
mem::replace(self, parser_snapshot_before_ty);
1040-
self.recover_arg_parse()?
1041-
}
1042-
}
1043-
};
1044-
1045-
let span = lo.to(self.token.span);
1046-
1047-
Ok(Param {
1048-
attrs: attrs.into(),
1049-
id: ast::DUMMY_NODE_ID,
1050-
is_placeholder: false,
1051-
pat,
1052-
span,
1053-
ty,
1054-
})
1055-
}
1056-
1057957
/// Parses mutability (`mut` or nothing).
1058958
fn parse_mutability(&mut self) -> Mutability {
1059959
if self.eat_keyword(kw::Mut) {
@@ -1267,49 +1167,112 @@ impl<'a> Parser<'a> {
12671167
Ok(params)
12681168
}
12691169

1270-
fn is_isolated_self(&self, n: usize) -> bool {
1271-
self.is_keyword_ahead(n, &[kw::SelfLower])
1272-
&& self.look_ahead(n + 1, |t| t != &token::ModSep)
1273-
}
1170+
/// Parses the parameter list and result type of a function that may have a `self` parameter.
1171+
fn parse_fn_decl_with_self(
1172+
&mut self,
1173+
is_name_required: impl Copy + Fn(&token::Token) -> bool,
1174+
) -> PResult<'a, P<FnDecl>> {
1175+
// Parse the arguments, starting out with `self` being allowed...
1176+
let mut is_self_allowed = true;
1177+
let (mut inputs, _): (Vec<_>, _) = self.parse_paren_comma_seq(|p| {
1178+
let res = p.parse_param_general(is_self_allowed, true, false, is_name_required);
1179+
// ...but now that we've parsed the first argument, `self` is no longer allowed.
1180+
is_self_allowed = false;
1181+
res
1182+
})?;
12741183

1275-
fn is_isolated_mut_self(&self, n: usize) -> bool {
1276-
self.is_keyword_ahead(n, &[kw::Mut])
1277-
&& self.is_isolated_self(n + 1)
1184+
// Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
1185+
self.deduplicate_recovered_params_names(&mut inputs);
1186+
1187+
Ok(P(FnDecl {
1188+
inputs,
1189+
output: self.parse_ret_ty(true)?,
1190+
}))
12781191
}
12791192

1280-
fn expect_self_ident(&mut self) -> Ident {
1281-
match self.token.kind {
1282-
// Preserve hygienic context.
1283-
token::Ident(name, _) => {
1284-
let span = self.token.span;
1285-
self.bump();
1286-
Ident::new(name, span)
1287-
}
1288-
_ => unreachable!(),
1193+
/// Skips unexpected attributes and doc comments in this position and emits an appropriate
1194+
/// error.
1195+
/// This version of parse param doesn't necessarily require identifier names.
1196+
fn parse_param_general(
1197+
&mut self,
1198+
is_self_allowed: bool,
1199+
is_trait_item: bool,
1200+
allow_c_variadic: bool,
1201+
is_name_required: impl Fn(&token::Token) -> bool,
1202+
) -> PResult<'a, Param> {
1203+
let lo = self.token.span;
1204+
let attrs = self.parse_outer_attributes()?;
1205+
1206+
// Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
1207+
if let Some(mut param) = self.parse_self_param()? {
1208+
param.attrs = attrs.into();
1209+
return if is_self_allowed {
1210+
Ok(param)
1211+
} else {
1212+
self.recover_bad_self_param(param, is_trait_item)
1213+
};
12891214
}
1290-
}
12911215

1292-
/// Recover for the grammar `*self`, `*const self`, and `*mut self`.
1293-
fn recover_self_ptr(&mut self) -> PResult<'a, (ast::SelfKind, Ident, Span)> {
1294-
let msg = "cannot pass `self` by raw pointer";
1295-
let span = self.token.span;
1296-
self.struct_span_err(span, msg)
1297-
.span_label(span, msg)
1298-
.emit();
1216+
let is_name_required = is_name_required(&self.token);
1217+
let (pat, ty) = if is_name_required || self.is_named_param() {
1218+
debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
12991219

1300-
Ok((SelfKind::Value(Mutability::Immutable), self.expect_self_ident(), self.prev_span))
1301-
}
1220+
let pat = self.parse_fn_param_pat()?;
1221+
if let Err(mut err) = self.expect(&token::Colon) {
1222+
if let Some(ident) = self.parameter_without_type(
1223+
&mut err,
1224+
pat,
1225+
is_name_required,
1226+
is_trait_item,
1227+
) {
1228+
err.emit();
1229+
return Ok(dummy_arg(ident));
1230+
} else {
1231+
return Err(err);
1232+
}
1233+
}
13021234

1303-
/// Parse `self` or `self: TYPE`. We already know the current token is `self`.
1304-
fn parse_self_possibly_typed(&mut self, m: Mutability) -> PResult<'a, (SelfKind, Ident, Span)> {
1305-
let eself_ident = self.expect_self_ident();
1306-
let eself_hi = self.prev_span;
1307-
let eself = if self.eat(&token::Colon) {
1308-
SelfKind::Explicit(self.parse_ty()?, m)
1235+
self.eat_incorrect_doc_comment_for_param_type();
1236+
(pat, self.parse_ty_common(true, true, allow_c_variadic)?)
13091237
} else {
1310-
SelfKind::Value(m)
1238+
debug!("parse_param_general ident_to_pat");
1239+
let parser_snapshot_before_ty = self.clone();
1240+
self.eat_incorrect_doc_comment_for_param_type();
1241+
let mut ty = self.parse_ty_common(true, true, allow_c_variadic);
1242+
if ty.is_ok() && self.token != token::Comma &&
1243+
self.token != token::CloseDelim(token::Paren) {
1244+
// This wasn't actually a type, but a pattern looking like a type,
1245+
// so we are going to rollback and re-parse for recovery.
1246+
ty = self.unexpected();
1247+
}
1248+
match ty {
1249+
Ok(ty) => {
1250+
let ident = Ident::new(kw::Invalid, self.prev_span);
1251+
let bm = BindingMode::ByValue(Mutability::Immutable);
1252+
let pat = self.mk_pat_ident(ty.span, bm, ident);
1253+
(pat, ty)
1254+
}
1255+
// If this is a C-variadic argument and we hit an error, return the error.
1256+
Err(err) if self.token == token::DotDotDot => return Err(err),
1257+
// Recover from attempting to parse the argument as a type without pattern.
1258+
Err(mut err) => {
1259+
err.cancel();
1260+
mem::replace(self, parser_snapshot_before_ty);
1261+
self.recover_arg_parse()?
1262+
}
1263+
}
13111264
};
1312-
Ok((eself, eself_ident, eself_hi))
1265+
1266+
let span = lo.to(self.token.span);
1267+
1268+
Ok(Param {
1269+
attrs: attrs.into(),
1270+
id: ast::DUMMY_NODE_ID,
1271+
is_placeholder: false,
1272+
pat,
1273+
span,
1274+
ty,
1275+
})
13131276
}
13141277

13151278
/// Returns the parsed optional self parameter and whether a self shortcut was used.
@@ -1378,27 +1341,64 @@ impl<'a> Parser<'a> {
13781341
Ok(Some(Param::from_self(ThinVec::default(), eself, eself_ident)))
13791342
}
13801343

1381-
/// Parses the parameter list and result type of a function that may have a `self` parameter.
1382-
fn parse_fn_decl_with_self(
1383-
&mut self,
1384-
is_name_required: impl Copy + Fn(&token::Token) -> bool,
1385-
) -> PResult<'a, P<FnDecl>> {
1386-
// Parse the arguments, starting out with `self` being allowed...
1387-
let mut is_self_allowed = true;
1388-
let (mut inputs, _): (Vec<_>, _) = self.parse_paren_comma_seq(|p| {
1389-
let res = p.parse_param_general(is_self_allowed, true, false, is_name_required);
1390-
// ...but now that we've parsed the first argument, `self` is no longer allowed.
1391-
is_self_allowed = false;
1392-
res
1393-
})?;
1344+
fn is_named_param(&self) -> bool {
1345+
let offset = match self.token.kind {
1346+
token::Interpolated(ref nt) => match **nt {
1347+
token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon),
1348+
_ => 0,
1349+
}
1350+
token::BinOp(token::And) | token::AndAnd => 1,
1351+
_ if self.token.is_keyword(kw::Mut) => 1,
1352+
_ => 0,
1353+
};
13941354

1395-
// Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
1396-
self.deduplicate_recovered_params_names(&mut inputs);
1355+
self.look_ahead(offset, |t| t.is_ident()) &&
1356+
self.look_ahead(offset + 1, |t| t == &token::Colon)
1357+
}
13971358

1398-
Ok(P(FnDecl {
1399-
inputs,
1400-
output: self.parse_ret_ty(true)?,
1401-
}))
1359+
fn is_isolated_self(&self, n: usize) -> bool {
1360+
self.is_keyword_ahead(n, &[kw::SelfLower])
1361+
&& self.look_ahead(n + 1, |t| t != &token::ModSep)
1362+
}
1363+
1364+
fn is_isolated_mut_self(&self, n: usize) -> bool {
1365+
self.is_keyword_ahead(n, &[kw::Mut])
1366+
&& self.is_isolated_self(n + 1)
1367+
}
1368+
1369+
fn expect_self_ident(&mut self) -> Ident {
1370+
match self.token.kind {
1371+
// Preserve hygienic context.
1372+
token::Ident(name, _) => {
1373+
let span = self.token.span;
1374+
self.bump();
1375+
Ident::new(name, span)
1376+
}
1377+
_ => unreachable!(),
1378+
}
1379+
}
1380+
1381+
/// Recover for the grammar `*self`, `*const self`, and `*mut self`.
1382+
fn recover_self_ptr(&mut self) -> PResult<'a, (ast::SelfKind, Ident, Span)> {
1383+
let msg = "cannot pass `self` by raw pointer";
1384+
let span = self.token.span;
1385+
self.struct_span_err(span, msg)
1386+
.span_label(span, msg)
1387+
.emit();
1388+
1389+
Ok((SelfKind::Value(Mutability::Immutable), self.expect_self_ident(), self.prev_span))
1390+
}
1391+
1392+
/// Parse `self` or `self: TYPE`. We already know the current token is `self`.
1393+
fn parse_self_possibly_typed(&mut self, m: Mutability) -> PResult<'a, (SelfKind, Ident, Span)> {
1394+
let eself_ident = self.expect_self_ident();
1395+
let eself_hi = self.prev_span;
1396+
let eself = if self.eat(&token::Colon) {
1397+
SelfKind::Explicit(self.parse_ty()?, m)
1398+
} else {
1399+
SelfKind::Value(m)
1400+
};
1401+
Ok((eself, eself_ident, eself_hi))
14021402
}
14031403

14041404
fn is_crate_vis(&self) -> bool {

0 commit comments

Comments
 (0)