@@ -210,30 +210,12 @@ impl<'a> Parser<'a> {
210
210
lhs = self . parse_assoc_op_cast ( lhs, lhs_span, ExprKind :: Cast ) ?;
211
211
continue ;
212
212
} 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) ?;
218
214
continue ;
219
215
} else if op == AssocOp :: DotDot || op == AssocOp :: DotDotEq {
220
216
// If we didn’t have to handle `x..`/`x..=`, it would be pretty easy to
221
217
// 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) ?;
237
219
break ;
238
220
}
239
221
@@ -393,6 +375,27 @@ impl<'a> Parser<'a> {
393
375
&& !classify:: expr_requires_semi_to_be_stmt ( e)
394
376
}
395
377
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
+
396
399
fn is_at_start_of_range_notation_rhs ( & self ) -> bool {
397
400
if self . token . can_begin_expr ( ) {
398
401
// Parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
@@ -615,6 +618,14 @@ impl<'a> Parser<'a> {
615
618
}
616
619
}
617
620
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
+
618
629
/// Parse `& mut? <expr>` or `& raw [ const | mut ] <expr>`.
619
630
fn parse_borrow_expr ( & mut self , lo : Span ) -> PResult < ' a , ( Span , ExprKind ) > {
620
631
self . expect_and ( ) ?;
0 commit comments