@@ -2602,53 +2602,50 @@ impl<'a> Parser<'a> {
26022602 pub fn parse_prefix_expr ( & mut self ) -> PResult < P < Expr > > {
26032603 let lo = self . span . lo ;
26042604 let hi;
2605-
26062605 // 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+ } ;
26522649 return Ok ( self . mk_expr ( lo, hi, ex) ) ;
26532650 }
26542651
@@ -2657,35 +2654,15 @@ impl<'a> Parser<'a> {
26572654 /// This parses an expression accounting for associativity and precedence of the operators in
26582655 /// the expression.
26592656 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 )
26832658 }
26842659
26852660 /// Parse an associative expression with operators of at least `min_prec` precedence
26862661 pub fn parse_assoc_expr_with ( & mut self , min_prec : usize , lhs : Option < P < Expr > > ) -> PResult < P < Expr > > {
26872662 let mut lhs = if lhs. is_some ( ) {
26882663 lhs. unwrap ( )
2664+ } else if self . token == token:: DotDot {
2665+ return self . parse_prefix_range_expr ( ) ;
26892666 } else {
26902667 try!( self . parse_prefix_expr ( ) )
26912668 } ;
@@ -2710,13 +2687,10 @@ impl<'a> Parser<'a> {
27102687 continue
27112688 } else if op == AssocOp :: DotDot {
27122689 // 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.
27172691 //
27182692 // 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.
27202694 let rhs = if self . is_at_start_of_range_notation_rhs ( ) {
27212695 self . parse_assoc_expr_with ( op. precedence ( ) + 1 , None ) . ok ( )
27222696 } else {
@@ -2800,6 +2774,26 @@ impl<'a> Parser<'a> {
28002774 }
28012775 }
28022776
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+
28032797 fn is_at_start_of_range_notation_rhs ( & self ) -> bool {
28042798 if self . token . can_begin_expr ( ) {
28052799 // parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
0 commit comments