@@ -2602,53 +2602,50 @@ impl<'a> Parser<'a> {
2602
2602
pub fn parse_prefix_expr ( & mut self ) -> PResult < P < Expr > > {
2603
2603
let lo = self . span . lo ;
2604
2604
let hi;
2605
-
2606
2605
// Note: when adding new unary operators, don't forget to adjust Token::can_begin_expr()
2607
- let ex;
2608
- match self . token {
2609
- token:: Not => {
2610
- try!( self . bump ( ) ) ;
2611
- let e = try!( self . parse_prefix_expr ( ) ) ;
2612
- hi = e. span . hi ;
2613
- ex = self . mk_unary ( UnNot , e) ;
2614
- }
2615
- token:: BinOp ( token:: Minus ) => {
2616
- try!( self . bump ( ) ) ;
2617
- let e = try!( self . parse_prefix_expr ( ) ) ;
2618
- hi = e. span . hi ;
2619
- ex = self . mk_unary ( UnNeg , e) ;
2620
- }
2621
- token:: BinOp ( token:: Star ) => {
2622
- try!( self . bump ( ) ) ;
2623
- let e = try!( self . parse_prefix_expr ( ) ) ;
2624
- hi = e. span . hi ;
2625
- ex = self . mk_unary ( UnDeref , e) ;
2626
- }
2627
- token:: BinOp ( token:: And ) | token:: AndAnd => {
2628
- try!( self . expect_and ( ) ) ;
2629
- let m = try!( self . parse_mutability ( ) ) ;
2630
- let e = try!( self . parse_prefix_expr ( ) ) ;
2631
- hi = e. span . hi ;
2632
- ex = ExprAddrOf ( m, e) ;
2633
- }
2634
- token:: Ident ( ..) if self . token . is_keyword ( keywords:: In ) => {
2635
- try!( self . bump ( ) ) ;
2636
- let place = try!( self . parse_expr_res ( Restrictions :: RESTRICTION_NO_STRUCT_LITERAL ) ) ;
2637
- let blk = try!( self . parse_block ( ) ) ;
2638
- let span = blk. span ;
2639
- hi = span. hi ;
2640
- let blk_expr = self . mk_expr ( span. lo , span. hi , ExprBlock ( blk) ) ;
2641
- self . span_warn ( span, "in PLACE BLOCK syntax is deprecated and will be removed soon" ) ;
2642
- ex = ExprInPlace ( place, blk_expr) ;
2643
- }
2644
- token:: Ident ( ..) if self . token . is_keyword ( keywords:: Box ) => {
2645
- try!( self . bump ( ) ) ;
2646
- let subexpression = try!( self . parse_prefix_expr ( ) ) ;
2647
- hi = subexpression. span . hi ;
2648
- ex = ExprBox ( subexpression) ;
2649
- }
2650
- _ => return self . parse_dot_or_call_expr ( )
2651
- }
2606
+ let ex = match self . token {
2607
+ token:: Not => {
2608
+ try!( self . bump ( ) ) ;
2609
+ let e = try!( self . parse_prefix_expr ( ) ) ;
2610
+ hi = e. span . hi ;
2611
+ self . mk_unary ( UnNot , e)
2612
+ }
2613
+ token:: BinOp ( token:: Minus ) => {
2614
+ try!( self . bump ( ) ) ;
2615
+ let e = try!( self . parse_prefix_expr ( ) ) ;
2616
+ hi = e. span . hi ;
2617
+ self . mk_unary ( UnNeg , e)
2618
+ }
2619
+ token:: BinOp ( token:: Star ) => {
2620
+ try!( self . bump ( ) ) ;
2621
+ let e = try!( self . parse_prefix_expr ( ) ) ;
2622
+ hi = e. span . hi ;
2623
+ self . mk_unary ( UnDeref , e)
2624
+ }
2625
+ token:: BinOp ( token:: And ) | token:: AndAnd => {
2626
+ try!( self . expect_and ( ) ) ;
2627
+ let m = try!( self . parse_mutability ( ) ) ;
2628
+ let e = try!( self . parse_prefix_expr ( ) ) ;
2629
+ hi = e. span . hi ;
2630
+ ExprAddrOf ( m, e)
2631
+ }
2632
+ token:: Ident ( ..) if self . token . is_keyword ( keywords:: In ) => {
2633
+ try!( self . bump ( ) ) ;
2634
+ let place = try!( self . parse_expr_res ( Restrictions :: RESTRICTION_NO_STRUCT_LITERAL ) ) ;
2635
+ let blk = try!( self . parse_block ( ) ) ;
2636
+ let span = blk. span ;
2637
+ hi = span. hi ;
2638
+ let blk_expr = self . mk_expr ( span. lo , span. hi , ExprBlock ( blk) ) ;
2639
+ ExprInPlace ( place, blk_expr)
2640
+ }
2641
+ token:: Ident ( ..) if self . token . is_keyword ( keywords:: Box ) => {
2642
+ try!( self . bump ( ) ) ;
2643
+ let subexpression = try!( self . parse_prefix_expr ( ) ) ;
2644
+ hi = subexpression. span . hi ;
2645
+ ExprBox ( subexpression)
2646
+ }
2647
+ _ => return self . parse_dot_or_call_expr ( )
2648
+ } ;
2652
2649
return Ok ( self . mk_expr ( lo, hi, ex) ) ;
2653
2650
}
2654
2651
@@ -2657,35 +2654,15 @@ impl<'a> Parser<'a> {
2657
2654
/// This parses an expression accounting for associativity and precedence of the operators in
2658
2655
/// the expression.
2659
2656
pub fn parse_assoc_expr ( & mut self ) -> PResult < P < Expr > > {
2660
- if self . token == token:: DotDot {
2661
- // prefix-form of range notation `..expr` and `..`
2662
- // This has the precedence just higher than assignment expressions (much lower than
2663
- // other prefix expressions) to be consistent with the postfix-form `expr..`
2664
- // If it isn’t clear yet, this is a hack of the worst kind (one that also probably
2665
- // can’t be fixed anymore because stability guarantees).
2666
- let lo = self . span . lo ;
2667
- let mut hi = self . span . hi ;
2668
- try!( self . bump ( ) ) ;
2669
- let opt_end = if self . is_at_start_of_range_notation_rhs ( ) {
2670
- // RHS must be parsed with more associativity than DotDot.
2671
- let next_prec = AssocOp :: from_token ( & token:: DotDot ) . unwrap ( ) . precedence ( ) + 1 ;
2672
- let end = try!( self . parse_assoc_expr_with ( next_prec, None ) ) ;
2673
- hi = end. span . hi ;
2674
- Some ( end)
2675
- } else {
2676
- None
2677
- } ;
2678
- let r = self . mk_range ( None , opt_end) ;
2679
- Ok ( self . mk_expr ( lo, hi, r) )
2680
- } else {
2681
- self . parse_assoc_expr_with ( 0 , None )
2682
- }
2657
+ self . parse_assoc_expr_with ( 0 , None )
2683
2658
}
2684
2659
2685
2660
/// Parse an associative expression with operators of at least `min_prec` precedence
2686
2661
pub fn parse_assoc_expr_with ( & mut self , min_prec : usize , lhs : Option < P < Expr > > ) -> PResult < P < Expr > > {
2687
2662
let mut lhs = if lhs. is_some ( ) {
2688
2663
lhs. unwrap ( )
2664
+ } else if self . token == token:: DotDot {
2665
+ return self . parse_prefix_range_expr ( ) ;
2689
2666
} else {
2690
2667
try!( self . parse_prefix_expr ( ) )
2691
2668
} ;
@@ -2710,13 +2687,10 @@ impl<'a> Parser<'a> {
2710
2687
continue
2711
2688
} else if op == AssocOp :: DotDot {
2712
2689
// If we didn’t have to handle `x..`, it would be pretty easy to generalise
2713
- // here by simply doing something along the lines of
2714
- //
2715
- // break_from_this_loop_after_setting_lhs = true;
2716
- // rhs = self.parse_assoc_expr_with(op.precedence() + 1, None);
2690
+ // it to the Fixity::None code.
2717
2691
//
2718
2692
// We have 2 alternatives here: `x..y` and `x..` The other two variants are
2719
- // handled in `parse_assoc_expr`
2693
+ // handled with `parse_prefix_range_expr` call above.
2720
2694
let rhs = if self . is_at_start_of_range_notation_rhs ( ) {
2721
2695
self . parse_assoc_expr_with ( op. precedence ( ) + 1 , None ) . ok ( )
2722
2696
} else {
@@ -2800,6 +2774,26 @@ impl<'a> Parser<'a> {
2800
2774
}
2801
2775
}
2802
2776
2777
+ /// Parse prefix-forms of range notation: `..expr` and `..`
2778
+ fn parse_prefix_range_expr ( & mut self ) -> PResult < P < Expr > > {
2779
+ debug_assert ! ( self . token == token:: DotDot ) ;
2780
+ let lo = self . span . lo ;
2781
+ let mut hi = self . span . hi ;
2782
+ try!( self . bump ( ) ) ;
2783
+ let opt_end = if self . is_at_start_of_range_notation_rhs ( ) {
2784
+ // RHS must be parsed with more associativity than DotDot.
2785
+ let next_prec = AssocOp :: from_token ( & token:: DotDot ) . unwrap ( ) . precedence ( ) + 1 ;
2786
+ Some ( try!( self . parse_assoc_expr_with ( next_prec, None ) . map ( |x|{
2787
+ hi = x. span . hi ;
2788
+ x
2789
+ } ) ) )
2790
+ } else {
2791
+ None
2792
+ } ;
2793
+ let r = self . mk_range ( None , opt_end) ;
2794
+ Ok ( self . mk_expr ( lo, hi, r) )
2795
+ }
2796
+
2803
2797
fn is_at_start_of_range_notation_rhs ( & self ) -> bool {
2804
2798
if self . token . can_begin_expr ( ) {
2805
2799
// parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
0 commit comments