Skip to content

Commit abce488

Browse files
committed
split parse_angle_args into loop / single step
1 parent 91194f7 commit abce488

File tree

1 file changed

+67
-63
lines changed

1 file changed

+67
-63
lines changed

src/librustc_parse/parser/path.rs

+67-63
Original file line numberDiff line numberDiff line change
@@ -388,73 +388,77 @@ impl<'a> Parser<'a> {
388388
/// possibly including trailing comma.
389389
fn parse_angle_args(&mut self) -> PResult<'a, Vec<AngleBracketedArg>> {
390390
let mut args = Vec::new();
391-
loop {
392-
if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
393-
// Parse lifetime argument.
394-
args.push(AngleBracketedArg::Arg(GenericArg::Lifetime(self.expect_lifetime())));
395-
} else if self.check_ident()
396-
&& self.look_ahead(1, |t| matches!(t.kind, token::Eq | token::Colon))
397-
{
398-
// Parse associated type constraint.
399-
let lo = self.token.span;
400-
let ident = self.parse_ident()?;
401-
let kind = if self.eat(&token::Eq) {
402-
AssocTyConstraintKind::Equality { ty: self.parse_ty()? }
403-
} else if self.eat(&token::Colon) {
404-
let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?;
405-
AssocTyConstraintKind::Bound { bounds }
406-
} else {
407-
unreachable!();
408-
};
409-
410-
let span = lo.to(self.prev_token.span);
411-
412-
// Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
413-
if let AssocTyConstraintKind::Bound { .. } = kind {
414-
self.sess.gated_spans.gate(sym::associated_type_bounds, span);
415-
}
416-
417-
let constraint = AssocTyConstraint { id: ast::DUMMY_NODE_ID, ident, kind, span };
418-
args.push(AngleBracketedArg::Constraint(constraint));
419-
} else if self.check_const_arg() {
420-
// Parse const argument.
421-
let expr = if let token::OpenDelim(token::Brace) = self.token.kind {
422-
self.parse_block_expr(
423-
None,
424-
self.token.span,
425-
BlockCheckMode::Default,
426-
ast::AttrVec::new(),
427-
)?
428-
} else if self.token.is_ident() {
429-
// FIXME(const_generics): to distinguish between idents for types and consts,
430-
// we should introduce a GenericArg::Ident in the AST and distinguish when
431-
// lowering to the HIR. For now, idents for const args are not permitted.
432-
if self.token.is_bool_lit() {
433-
self.parse_literal_maybe_minus()?
434-
} else {
435-
let span = self.token.span;
436-
let msg = "identifiers may currently not be used for const generics";
437-
self.struct_span_err(span, msg).emit();
438-
let block = self.mk_block_err(span);
439-
self.mk_expr(span, ast::ExprKind::Block(block, None), ast::AttrVec::new())
440-
}
441-
} else {
442-
self.parse_literal_maybe_minus()?
443-
};
444-
let value = AnonConst { id: ast::DUMMY_NODE_ID, value: expr };
445-
args.push(AngleBracketedArg::Arg(GenericArg::Const(value)));
446-
} else if self.check_type() {
447-
// Parse type argument.
448-
args.push(AngleBracketedArg::Arg(GenericArg::Type(self.parse_ty()?)));
449-
} else {
450-
break;
451-
}
452-
391+
while let Some(arg) = self.parse_angle_arg()? {
392+
args.push(arg);
453393
if !self.eat(&token::Comma) {
454394
break;
455395
}
456396
}
457-
458397
Ok(args)
459398
}
399+
400+
/// Parses a single argument in the angle arguments `<...>` of a path segment.
401+
fn parse_angle_arg(&mut self) -> PResult<'a, Option<AngleBracketedArg>> {
402+
let arg = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
403+
// Parse lifetime argument.
404+
AngleBracketedArg::Arg(GenericArg::Lifetime(self.expect_lifetime()))
405+
} else if self.check_ident()
406+
&& self.look_ahead(1, |t| matches!(t.kind, token::Eq | token::Colon))
407+
{
408+
// Parse associated type constraint.
409+
let lo = self.token.span;
410+
let ident = self.parse_ident()?;
411+
let kind = if self.eat(&token::Eq) {
412+
AssocTyConstraintKind::Equality { ty: self.parse_ty()? }
413+
} else if self.eat(&token::Colon) {
414+
let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?;
415+
AssocTyConstraintKind::Bound { bounds }
416+
} else {
417+
unreachable!();
418+
};
419+
420+
let span = lo.to(self.prev_token.span);
421+
422+
// Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
423+
if let AssocTyConstraintKind::Bound { .. } = kind {
424+
self.sess.gated_spans.gate(sym::associated_type_bounds, span);
425+
}
426+
427+
let constraint = AssocTyConstraint { id: ast::DUMMY_NODE_ID, ident, kind, span };
428+
AngleBracketedArg::Constraint(constraint)
429+
} else if self.check_const_arg() {
430+
// Parse const argument.
431+
let expr = if let token::OpenDelim(token::Brace) = self.token.kind {
432+
self.parse_block_expr(
433+
None,
434+
self.token.span,
435+
BlockCheckMode::Default,
436+
ast::AttrVec::new(),
437+
)?
438+
} else if self.token.is_ident() {
439+
// FIXME(const_generics): to distinguish between idents for types and consts,
440+
// we should introduce a GenericArg::Ident in the AST and distinguish when
441+
// lowering to the HIR. For now, idents for const args are not permitted.
442+
if self.token.is_bool_lit() {
443+
self.parse_literal_maybe_minus()?
444+
} else {
445+
let span = self.token.span;
446+
let msg = "identifiers may currently not be used for const generics";
447+
self.struct_span_err(span, msg).emit();
448+
let block = self.mk_block_err(span);
449+
self.mk_expr(span, ast::ExprKind::Block(block, None), ast::AttrVec::new())
450+
}
451+
} else {
452+
self.parse_literal_maybe_minus()?
453+
};
454+
let value = AnonConst { id: ast::DUMMY_NODE_ID, value: expr };
455+
AngleBracketedArg::Arg(GenericArg::Const(value))
456+
} else if self.check_type() {
457+
// Parse type argument.
458+
AngleBracketedArg::Arg(GenericArg::Type(self.parse_ty()?))
459+
} else {
460+
return Ok(None);
461+
};
462+
Ok(Some(arg))
463+
}
460464
}

0 commit comments

Comments
 (0)