Skip to content

Commit 05c26a4

Browse files
committed
refactor assoc op parsing
1 parent e43a7ef commit 05c26a4

File tree

1 file changed

+31
-20
lines changed

1 file changed

+31
-20
lines changed

src/librustc_parse/parser/expr.rs

+31-20
Original file line numberDiff line numberDiff line change
@@ -210,30 +210,12 @@ impl<'a> Parser<'a> {
210210
lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?;
211211
continue;
212212
} else if op == AssocOp::Colon {
213-
let maybe_path = self.could_ascription_be_path(&lhs.kind);
214-
self.last_type_ascription = Some((self.prev_span, maybe_path));
215-
216-
lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?;
217-
self.sess.gated_spans.gate(sym::type_ascription, lhs.span);
213+
lhs = self.parse_assoc_op_ascribe(lhs, lhs_span)?;
218214
continue;
219215
} else if op == AssocOp::DotDot || op == AssocOp::DotDotEq {
220216
// If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to
221217
// generalise it to the Fixity::None code.
222-
//
223-
// We have 2 alternatives here: `x..y`/`x..=y` and `x..`/`x..=` The other
224-
// two variants are handled with `parse_prefix_range_expr` call above.
225-
let rhs = if self.is_at_start_of_range_notation_rhs() {
226-
Some(self.parse_assoc_expr_with(prec + 1, LhsExpr::NotYetParsed)?)
227-
} else {
228-
None
229-
};
230-
let (lhs_span, rhs_span) =
231-
(lhs.span, if let Some(ref x) = rhs { x.span } else { cur_op_span });
232-
let limits =
233-
if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed };
234-
235-
let r = self.mk_range(Some(lhs), rhs, limits)?;
236-
lhs = self.mk_expr(lhs_span.to(rhs_span), r, AttrVec::new());
218+
lhs = self.parse_range_expr(prec, lhs, op, cur_op_span)?;
237219
break;
238220
}
239221

@@ -393,6 +375,27 @@ impl<'a> Parser<'a> {
393375
&& !classify::expr_requires_semi_to_be_stmt(e)
394376
}
395377

378+
/// Parses `x..y`, `x..=y`, and `x..`/`x..=`.
379+
/// The other two variants are handled in `parse_prefix_range_expr` below.
380+
fn parse_range_expr(
381+
&mut self,
382+
prec: usize,
383+
lhs: P<Expr>,
384+
op: AssocOp,
385+
cur_op_span: Span,
386+
) -> PResult<'a, P<Expr>> {
387+
let rhs = if self.is_at_start_of_range_notation_rhs() {
388+
Some(self.parse_assoc_expr_with(prec + 1, LhsExpr::NotYetParsed)?)
389+
} else {
390+
None
391+
};
392+
let rhs_span = rhs.as_ref().map_or(cur_op_span, |x| x.span);
393+
let span = lhs.span.to(rhs_span);
394+
let limits =
395+
if op == AssocOp::DotDot { RangeLimits::HalfOpen } else { RangeLimits::Closed };
396+
Ok(self.mk_expr(span, self.mk_range(Some(lhs), rhs, limits)?, AttrVec::new()))
397+
}
398+
396399
fn is_at_start_of_range_notation_rhs(&self) -> bool {
397400
if self.token.can_begin_expr() {
398401
// Parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
@@ -615,6 +618,14 @@ impl<'a> Parser<'a> {
615618
}
616619
}
617620

621+
fn parse_assoc_op_ascribe(&mut self, lhs: P<Expr>, lhs_span: Span) -> PResult<'a, P<Expr>> {
622+
let maybe_path = self.could_ascription_be_path(&lhs.kind);
623+
self.last_type_ascription = Some((self.prev_span, maybe_path));
624+
let lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type)?;
625+
self.sess.gated_spans.gate(sym::type_ascription, lhs.span);
626+
Ok(lhs)
627+
}
628+
618629
/// Parse `& mut? <expr>` or `& raw [ const | mut ] <expr>`.
619630
fn parse_borrow_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> {
620631
self.expect_and()?;

0 commit comments

Comments
 (0)